diff options
author | ttt | 2017-05-13 00:29:47 +0530 |
---|---|---|
committer | ttt | 2017-05-13 00:29:47 +0530 |
commit | abf599be33b383a6a5baf9493093b2126a622ac8 (patch) | |
tree | 4c5ab6e0d935d5e65fabcf0258e4a00dd20a5afa /sbhs_server | |
download | SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.gz SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.bz2 SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.zip |
added all server files
Diffstat (limited to 'sbhs_server')
115 files changed, 3977 insertions, 0 deletions
diff --git a/sbhs_server/__init__.py b/sbhs_server/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/__init__.py diff --git a/sbhs_server/__init__.pyc b/sbhs_server/__init__.pyc Binary files differnew file mode 100644 index 0000000..0241825 --- /dev/null +++ b/sbhs_server/__init__.pyc diff --git a/sbhs_server/_gitmodules b/sbhs_server/_gitmodules new file mode 100644 index 0000000..c69df91 --- /dev/null +++ b/sbhs_server/_gitmodules @@ -0,0 +1,8 @@ +[submodule "client_static"] + path = client_static + url = https://bitbucket.org/SBHS-virtual-labs/client_downloads.git +[submodule "sbhs_server/server_private_files"] + path = sbhs_server/server_private_files + url = https://bitbucket.org/SBHS-virtual-labs/server_private_files.git + + diff --git a/sbhs_server/account/__init__.py b/sbhs_server/account/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/account/__init__.py diff --git a/sbhs_server/account/__init__.pyc b/sbhs_server/account/__init__.pyc Binary files differnew file mode 100644 index 0000000..229f2e0 --- /dev/null +++ b/sbhs_server/account/__init__.pyc diff --git a/sbhs_server/account/admin.py b/sbhs_server/account/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/account/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/account/models.py b/sbhs_server/account/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/account/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/account/models.pyc b/sbhs_server/account/models.pyc Binary files differnew file mode 100644 index 0000000..782790e --- /dev/null +++ b/sbhs_server/account/models.pyc diff --git a/sbhs_server/account/tests.py b/sbhs_server/account/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/account/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/account/views.py b/sbhs_server/account/views.py new file mode 100644 index 0000000..306b318 --- /dev/null +++ b/sbhs_server/account/views.py @@ -0,0 +1,111 @@ +from django.shortcuts import render, redirect +from sbhs_server.tables.models import Account, Board +from django.core.exceptions import ValidationError +from django.core.validators import validate_email +from django.contrib import messages +from sbhs_server.helpers import simple_encrypt +from django.contrib.auth import authenticate +from django.contrib.auth import login as LOGIN +from django.contrib.auth import logout as LOGOUT +from django.contrib.auth.decorators import login_required +# Create your views here. + +def index(req): + if req.user.is_authenticated(): + return redirect(home) + return render(req, "account/index.html") + +def new(): + pass + +def create(req): + error = [] + + name = req.POST.get("name").strip() + email = req.POST.get("email").strip() + username = req.POST.get("username").strip() + roll_number = req.POST.get("roll_number").strip() + password = req.POST.get("password") + confirm = req.POST.get("confirm") + institute = req.POST.get("institute").strip() + department = req.POST.get("department").strip() + position = req.POST.get("position").strip() + + error = error + (["Please enter a name."] if name == "" else []) + error = error + (["Please enter an email."] if email == "" else []) + error = error + (["Please enter an username."] if username == "" else []) + error = error + (["Please enter a roll_number."] if roll_number == "" else []) + + error = error + (["Please enter a password."] if password == "" else []) + error = error + (["Password confirmation does not match."] if password != confirm else []) + + error = error + (["Please enter an institute."] if institute == "" else []) + error = error + (["Please enter a department."] if department == "" else []) + error = error + (["Please enter a position."] if position == "" else []) + + try: + validate_email(email) + except ValidationError: + error = error + ["Please enter a valid email."] + + email_exists = Account.objects.filter(email=email).count() + error = error + (["Account with given email already exists."] if email_exists > 0 else []) + + username_exists = Account.objects.filter(username=username).count() + error = error + (["Account with given username already exists."] if username_exists > 0 else []) + + if error != []: + messages.add_message(req, messages.ERROR, "<br>".join(error)) + return redirect(index) + + # try: + account = Account( + name=name, + username=username, + email=email, + board_id=Board.allot_board() + ) + account.set_password(password) + account.save() + account.send_confirmation() + print "Done" + messages.add_message(req, messages.SUCCESS, "You have been registered successfully. Please check your email for confirmation.") + return redirect(index) + # except: + # messages.add_message(req, messages.ERROR, "Invalid information. Please try again.") + # return redirect(index) + +def confirm(req, token): + try: + email = simple_encrypt.decrypt(token) + account = Account.objects.get(email=email) + account.is_active = True + account.save() + messages.add_message(req, messages.SUCCESS, "Your email has been confirmed. You can login now.") + except: + messages.add_message(req, messages.ERROR, "Invalid confirmation token.") + + return redirect(index) + +def login(req): + username = req.POST.get('username') + password = req.POST.get('password') + user = authenticate(username=username, password=password) + if user is not None: + if user.is_active: + LOGIN(req, user) + return redirect(index) + else: + messages.add_message(req, messages.ERROR, "Your account is not activated yet. Please check your email for activation link.") + return redirect(index) + else: + messages.add_message(req, messages.ERROR, "Invalid username or password.") + return redirect(index) + +def logout(req): + LOGOUT(req) + return redirect(index) + +@login_required(redirect_field_name=None) +def home(req): + return render(req, "account/home.html") diff --git a/sbhs_server/admin/__init__.py b/sbhs_server/admin/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/admin/__init__.py diff --git a/sbhs_server/admin/__init__.pyc b/sbhs_server/admin/__init__.pyc Binary files differnew file mode 100644 index 0000000..95dd17b --- /dev/null +++ b/sbhs_server/admin/__init__.pyc diff --git a/sbhs_server/admin/admin.py b/sbhs_server/admin/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/admin/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/admin/models.py b/sbhs_server/admin/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/admin/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/admin/models.pyc b/sbhs_server/admin/models.pyc Binary files differnew file mode 100644 index 0000000..2d2a7de --- /dev/null +++ b/sbhs_server/admin/models.pyc diff --git a/sbhs_server/admin/tests.py b/sbhs_server/admin/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/admin/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/admin/views.py b/sbhs_server/admin/views.py new file mode 100644 index 0000000..8289cfa --- /dev/null +++ b/sbhs_server/admin/views.py @@ -0,0 +1,75 @@ +from django.shortcuts import render, redirect +from django.http import Http404 +from django.contrib.auth.decorators import login_required +from sbhs_server.tables.models import Board, Booking +from sbhs_server import settings +import subprocess +# Create your views here. + +def checkadmin(req): + if not req.user.is_admin: + raise Http404 + +@login_required(redirect_field_name=None) +def index(req): + checkadmin(req) + boards = Board.objects.order_by('online').all() + allotment_mode = "Random" if Board.can_do_random_allotment() else "Workshop" + return render(req, 'admin/index.html', {"boards": boards, "allotment_mode": allotment_mode}) + +@login_required(redirect_field_name=None) +def toggle_allotment_mode(req): + checkadmin(req) + Board.toggle_random_allotment() + return redirect(index) + +@login_required(redirect_field_name=None) +def booking_index(req): + checkadmin(req) + bookings = Booking.objects.order_by('-booking_date').select_related()[:50] + return render(req, 'admin/booking_index.html', {"bookings": bookings}) + +@login_required(redirect_field_name=None) +def webcam_index(req): + checkadmin(req) + boards = Board.objects.all() + return render(req, 'admin/webcam_index.html', {"boards": boards}) + +@login_required(redirect_field_name=None) +def profile(req, mid): + checkadmin(req) + try: + filename = settings.SBHS_GLOBAL_LOG_DIR + "/" + mid + ".log" + f = open(filename, "r") + f.close() + except: + raise Http404 + + delta_T = 1000 + data = subprocess.check_output("tail -n %d %s" % (delta_T, filename), shell=True) + data = data.split("\n") + plot = [] + heatcsv = "" + fancsv = "" + tempcsv = "" + + for t in xrange(len(data)): + line = data[t] + entry = line.strip().split(" ") + try: + plot.append([int(i) for i in entry[0:-1] + [float(entry[-1])]]) + heatcsv += "%d,%s\\n" % (t+1, entry[1]) + fancsv += "%d,%s\\n" % (t+1, entry[2]) + tempcsv += "%d,%s\\n" % (t+1, entry[3]) + except: + continue + + plot = zip(*plot) # transpose + + return render(req, "admin/profile.html", { + "mid": mid, + "delta_T": delta_T, + "heat": heatcsv, + "fan": fancsv, + "temp": tempcsv + })
\ No newline at end of file diff --git a/sbhs_server/experiment/__init__.py b/sbhs_server/experiment/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/experiment/__init__.py diff --git a/sbhs_server/experiment/__init__.pyc b/sbhs_server/experiment/__init__.pyc Binary files differnew file mode 100644 index 0000000..32fcf1c --- /dev/null +++ b/sbhs_server/experiment/__init__.pyc diff --git a/sbhs_server/experiment/admin.py b/sbhs_server/experiment/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/experiment/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/experiment/models.py b/sbhs_server/experiment/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/experiment/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/experiment/models.pyc b/sbhs_server/experiment/models.pyc Binary files differnew file mode 100644 index 0000000..9af4264 --- /dev/null +++ b/sbhs_server/experiment/models.pyc diff --git a/sbhs_server/experiment/tests.py b/sbhs_server/experiment/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/experiment/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/experiment/views.py b/sbhs_server/experiment/views.py new file mode 100644 index 0000000..515d2b2 --- /dev/null +++ b/sbhs_server/experiment/views.py @@ -0,0 +1,221 @@ +from django.shortcuts import render +from django.http import HttpResponse +from django.contrib.auth.decorators import login_required +from django.contrib.auth import authenticate +from django.contrib.auth import login as LOGIN +from sbhs_server.tables.models import Slot, Account, Experiment, Booking +import json, datetime, os, time +from django.views.decorators.csrf import csrf_exempt +from sbhs_server import settings +# Create your views here. +# +def check_connection(req): + return HttpResponse("TESTOK") + +@csrf_exempt +def initiation(req): + username = req.POST.get("username") + password = req.POST.get("password") + user = authenticate(username=username, password=password) + if user is not None: + if user.is_active: + user1 = Account.objects.select_related().filter(id=user.id) + user1 = user1[0] + user_board = user1.board + if user_board.online: + slots = Slot.slots_now() + slot_ids = [s.id for s in slots] + now = datetime.datetime.now() + bookings = user.booking_set.filter(booking_date__year=now.year, + booking_date__month=now.month, + booking_date__day=now.day, + slot_id__in=slot_ids).select_related("slot") + try: + cur_booking = bookings[0] + active_slot = cur_booking.slot + except: + cur_booking = None + active_slot = None + + if active_slot is not None: + endtime = cur_booking.end_time() + if now < endtime: + filename = datetime.datetime.strftime(now, "%Y%b%d_%H_%M_%S.txt") + logdir = os.path.join(settings.EXPERIMENT_LOGS_DIR, user.username) + if not os.path.exists(logdir): + os.makedirs(logdir) + + f = open(os.path.join(logdir, filename), "a") + f.close() + + LOGIN(req, user) + + e = Experiment() + e.booking=cur_booking + e.log=os.path.join(logdir, filename) + e.save() + + key = str(user_board.mid) + + settings.boards[key]["experiment_id"] = e.id + reset(req) + + + STATUS = 1 + MESSAGE = filename + else: + reset(req) + 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." + else: + STATUS = 0 + MESSAGE = "Your SBHS is offline. Please contact the Vlabs team." + else: + STATUS = 0 + MESSAGE = "Your account is not activated yet. Please check your email for activation link." + else: + STATUS = 0 + MESSAGE = "Invalid username or password" + + return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE})) +# return HttpResponse(key) +# @login_required(redirect_field_name=None) +@csrf_exempt +def experiment(req): + try: + server_start_ts = int(time.time() * 1000) + from sbhs_server.settings import boards + user = req.user + key = str(user.board.mid) + experiment = Experiment.objects.select_related().filter(id=boards[key]["experiment_id"]) + + if len(experiment) == 1 and user.id == experiment[0].booking.account.id and experiment[0].booking.trashed_at == None: + experiment = experiment[0] + now = datetime.datetime.now() + endtime = experiment.booking.end_time() + if endtime > now: + timeleft = int((endtime-now).seconds) + heat = max(min(int(req.POST.get("heat")), 100), 0) + fan = max(min(int(req.POST.get("fan")), 100), 0) + + boards[key]["board"].setHeat(heat) + boards[key]["board"].setFan(fan) + temperature = boards[key]["board"].getTemp() + log_data(boards[key]["board"], key, heat=heat, fan=fan, temp=temperature) + + server_end_ts = int(time.time() * 1000) + + STATUS = 1 + MESSAGE = "%s %d %d %2.2f" % (req.POST.get("iteration"), + heat, + fan, + temperature) + MESSAGE = "%s %s %d %d,%s,%d" % (MESSAGE, + req.POST.get("timestamp"), + server_start_ts, + server_end_ts, + req.POST.get("variables"), timeleft) + + f = open(experiment.log, "a") + f.write(" ".join(MESSAGE.split(",")[:2]) + "\n") + f.close() + else: + boards[key]["board"].setHeat(0) + boards[key]["board"].setFan(100) + log_data(boards[key]["board"], key) + + STATUS = 0 + MESSAGE = "Slot has ended. Please book the next slot to continue the experiment." + + reset(req) + boards[key]["experiment_id"] = None + else: + STATUS = 0 + MESSAGE = "You haven't booked this slot." + + return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE})) + except Exception: + return HttpResponse(json.dumps({"STATUS": 0, "MESSAGE": "Invalid input. Perhaps the slot has ended. Please book the next slot to continue the experiment."})) + +@csrf_exempt +def reset(req): + try: + from sbhs_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) + if endtime < now: + boards[key]["experiment_id"] = None + except: + pass + + return HttpResponse("") + +def client_version(req): + return HttpResponse("3") + +@login_required(redirect_field_name=None) +def logs(req): + bookings = Booking.objects.only("id").filter(account__id=req.user.id) + deleted_bookings = Booking.trash.only("id").filter(account__id=req.user.id) + bookings = list(bookings) + list(deleted_bookings) + booking_ids = [b.id for b in bookings] + experiments = Experiment.objects.select_related("booking", "booking__slot").filter(booking_id__in=booking_ids) + for e in experiments: + e.logname = e.log.split("/")[-1] + return render(req, "experiment/logs.html", {"experiments": reversed(experiments)}) + +@login_required(redirect_field_name=None) +def download_log(req, experiment_id, fn): + try: + experiment = Experiment.objects.select_related("booking", "booking__account").get(id=experiment_id) + assert req.user.id == experiment.booking.account.id + f = open(experiment.log, "r") + data = f.read() + f.close() + return HttpResponse(data, content_type='text/text') + except: + return HttpResponse("Requested log file doesn't exist.") + +def log_data(sbhs, mid, heat=None, fan=None, temp=None): + f = open(settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log", "a") + 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)) + f.write(data) + f.close() + +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") diff --git a/sbhs_server/experiment/views.py.new b/sbhs_server/experiment/views.py.new new file mode 100644 index 0000000..004f852 --- /dev/null +++ b/sbhs_server/experiment/views.py.new @@ -0,0 +1,222 @@ +from django.shortcuts import render +from django.http import HttpResponse +from django.contrib.auth.decorators import login_required +from django.contrib.auth import authenticate +from django.contrib.auth import login as LOGIN +from sbhs_server.tables.models import Slot, Account, Experiment, Booking +import json, datetime, os, time +from django.views.decorators.csrf import csrf_exempt +from sbhs_server import settings +# Create your views here. +# +def check_connection(req): + return HttpResponse("TESTOK") + +@csrf_exempt +def initiation(req): + username = req.POST.get("username") + password = req.POST.get("password") + user = authenticate(username=username, password=password) + if user is not None: + if user.is_active: + user1 = Account.objects.select_related().filter(id=user.id) + user1 = user1[0] + user_board = user1.board + if user_board.online: + slots = Slot.slots_now() + slot_ids = [s.id for s in slots] + now = datetime.datetime.now() + bookings = user.booking_set.filter(booking_date__year=now.year, + booking_date__month=now.month, + booking_date__day=now.day, + slot_id__in=slot_ids).select_related("slot") + try: + cur_booking = bookings[0] + active_slot = cur_booking.slot + except: + cur_booking = None + active_slot = None + + if active_slot is not None: + endtime = cur_booking.end_time() + if now < endtime: + filename = datetime.datetime.strftime(now, "%Y%b%d_%H_%M_%S.txt") + logdir = os.path.join(settings.EXPERIMENT_LOGS_DIR, user.username) + if not os.path.exists(logdir): + os.makedirs(logdir) + + f = open(os.path.join(logdir, filename), "a") + f.close() + + LOGIN(req, user) + + e = Experiment() + e.booking=cur_booking + e.log=os.path.join(logdir, filename) + e.save() + + key = str(user_board.mid) + + settings.boards[key]["experiment_id"] = e.id + + + reset(req) + + STATUS = 1 + MESSAGE = filename + else: + reset(req) + 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." + else: + STATUS = 0 + MESSAGE = "Your SBHS is offline. Please contact the Vlabs team." + else: + STATUS = 0 + MESSAGE = "Your account is not activated yet. Please check your email for activation link." + else: + STATUS = 0 + MESSAGE = "Invalid username or password" + + return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE})) +# return HttpResponse(str(e.id), str(settings.board[key]) ) +#@login_required(redirect_field_name=None) +@csrf_exempt +def experiment(req): + try: + server_start_ts = int(time.time() * 1000) + from sbhs_server.settings import boards + user = req.user + key = str(user.board.mid) + experiment = Experiment.objects.select_related().filter(id=boards[key]["experiment_id"]) + + if len(experiment) == 1 and user.id == experiment[0].booking.account.id and experiment[0].booking.trashed_at == None: + experiment = experiment[0] + now = datetime.datetime.now() + endtime = experiment.booking.end_time() + if endtime > now: + timeleft = int((endtime-now).seconds) + heat = max(min(int(req.POST.get("heat")), 100), 0) + fan = max(min(int(req.POST.get("fan")), 100), 0) + + boards[key]["board"].setHeat(heat) + boards[key]["board"].setFan(fan) + temperature = boards[key]["board"].getTemp() + log_data(boards[key]["board"], key, heat=heat, fan=fan, temp=temperature) + + server_end_ts = int(time.time() * 1000) + + STATUS = 1 + MESSAGE = "%s %d %d %2.2f" % (req.POST.get("iteration"), + heat, + fan, + temperature) + MESSAGE = "%s %s %d %d,%s,%d" % (MESSAGE, + req.POST.get("timestamp"), + server_start_ts, + server_end_ts, + req.POST.get("variables"), timeleft) + + f = open(experiment.log, "a") + f.write(" ".join(MESSAGE.split(",")[:2]) + "\n") + f.close() + else: + boards[key]["board"].setHeat(0) + boards[key]["board"].setFan(100) + log_data(boards[key]["board"], key) + + STATUS = 0 + MESSAGE = "Slot has ended. Please book the next slot to continue the experiment." + + reset(req) + boards[key]["experiment_id"] = None + else: + STATUS = 0 + MESSAGE = "You haven't booked this slot." + + return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE})) + except Exception: + return HttpResponse(json.dumps({"STATUS": 0, "MESSAGE": "Invalid input. Perhaps the slot has ended. Please book the next slot to continue the experiment."})) + +@csrf_exempt +def reset(req): + try: + from sbhs_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) + if endtime < now: + boards[key]["experiment_id"] = None + except: + pass + + return HttpResponse("") + +def client_version(req): + return HttpResponse("3") + +@login_required(redirect_field_name=None) +def logs(req): + bookings = Booking.objects.only("id").filter(account__id=req.user.id) + deleted_bookings = Booking.trash.only("id").filter(account__id=req.user.id) + bookings = list(bookings) + list(deleted_bookings) + booking_ids = [b.id for b in bookings] + experiments = Experiment.objects.select_related("booking", "booking__slot").filter(booking_id__in=booking_ids) + for e in experiments: + e.logname = e.log.split("/")[-1] + return render(req, "experiment/logs.html", {"experiments": reversed(experiments)}) + +@login_required(redirect_field_name=None) +def download_log(req, experiment_id, fn): + try: + experiment = Experiment.objects.select_related("booking", "booking__account").get(id=experiment_id) + assert req.user.id == experiment.booking.account.id + f = open(experiment.log, "r") + data = f.read() + f.close() + return HttpResponse(data, content_type='text/text') + except: + return HttpResponse("Requested log file doesn't exist.") + +def log_data(sbhs, mid, heat=None, fan=None, temp=None): + f = open(settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log", "a") + 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)) + f.write(data) + f.close() + +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") diff --git a/sbhs_server/helpers/__init__.py b/sbhs_server/helpers/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/helpers/__init__.py diff --git a/sbhs_server/helpers/__init__.pyc b/sbhs_server/helpers/__init__.pyc Binary files differnew file mode 100644 index 0000000..e4b1769 --- /dev/null +++ b/sbhs_server/helpers/__init__.pyc diff --git a/sbhs_server/helpers/mailer.py b/sbhs_server/helpers/mailer.py new file mode 100644 index 0000000..7c58f95 --- /dev/null +++ b/sbhs_server/helpers/mailer.py @@ -0,0 +1,16 @@ +from sbhs_server import settings +import smtplib + +def email(to, subject, message): + smtpserver = smtplib.SMTP() + smtpserver.connect(settings.EMAIL_HOST, settings.EMAIL_PORT) + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.ehlo() + smtpserver.esmtp_features['auth']='LOGIN DIGEST-MD5 PLAIN' + smtpserver.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) + + header = 'To: ' + to + '\n' + 'From: ' + settings.EMAIL_HOST_USER + '@iitb.ac.in\n' + 'Subject: ' + subject +' \n' + msg = header + '\n' + message + '\n\n' + smtpserver.sendmail(settings.EMAIL_HOST_USER + '@iitb.ac.in', to, msg) + smtpserver.close()
\ No newline at end of file diff --git a/sbhs_server/helpers/mailer.pyc b/sbhs_server/helpers/mailer.pyc Binary files differnew file mode 100644 index 0000000..5105102 --- /dev/null +++ b/sbhs_server/helpers/mailer.pyc diff --git a/sbhs_server/helpers/simple_encrypt.py b/sbhs_server/helpers/simple_encrypt.py new file mode 100644 index 0000000..976fe4d --- /dev/null +++ b/sbhs_server/helpers/simple_encrypt.py @@ -0,0 +1,34 @@ +import base64 + +def encrypt(cleartext): + string = cleartext + + string = string[::-1] + + for i in xrange(3): + string = base64.b32encode(string) + string = string[::-1] + string = string.lower() + + padding = string.count("=") + string = string.replace("=", "") + return str(padding) + "." + string + + + +def decrypt(ciphertext): + data = ciphertext.split(".") + padding = int(data[0]) + cipher = data[1] + + for i in xrange(padding): + cipher = "=" + cipher + + string = cipher + + for i in xrange(3): + string = string.upper() + string = string[::-1] + string = base64.b32decode(string) + + return string[::-1]
\ No newline at end of file diff --git a/sbhs_server/helpers/simple_encrypt.pyc b/sbhs_server/helpers/simple_encrypt.pyc Binary files differnew file mode 100644 index 0000000..ffb331f --- /dev/null +++ b/sbhs_server/helpers/simple_encrypt.pyc diff --git a/sbhs_server/index.wsgi b/sbhs_server/index.wsgi new file mode 100644 index 0000000..2b8fc21 --- /dev/null +++ b/sbhs_server/index.wsgi @@ -0,0 +1,20 @@ +import os +import sys +import site + +# Add the site-packages of the chosen virtualenv to work with +site.addsitedir('/home/vlabs/sbhs_vlabs/sbhs/local/lib/python2.7/site-packages/') + +# Add the app's directory to the PYTHONPATHr +sys.path.append('/home/vlabs/sbhs_vlabs/sbhs/') +sys.path.append('/home/vlabs/sbhs_vlabs/sbhs/sbhs_server/') +sys.path.append('/home/vlabs/sbhs_vlabs/sbhs/sbhs_server/sbhs_server/') + +os.environ['DJANGO_SETTINGS_MODULE'] = 'sbhs_server.settings' + +# Activate your virtual env +activate_env=os.path.expanduser("/home/vlabs/sbhs_vlabs/sbhs/bin/activate_this.py") +execfile(activate_env, dict(__file__=activate_env)) + +import django.core.handlers.wsgi +application = django.core.handlers.wsgi.WSGIHandler() diff --git a/sbhs_server/load_homepage.py b/sbhs_server/load_homepage.py new file mode 100644 index 0000000..7a3113d --- /dev/null +++ b/sbhs_server/load_homepage.py @@ -0,0 +1,5 @@ +import urllib2 + +proxy_handler = urllib2.ProxyHandler({}) +opener = urllib2.build_opener(proxy_handler) +page = opener.open('http://vlabs.iitb.ac.in/sbhs/', timeout=20) diff --git a/sbhs_server/load_private_files.sh b/sbhs_server/load_private_files.sh new file mode 100644 index 0000000..9605fc9 --- /dev/null +++ b/sbhs_server/load_private_files.sh @@ -0,0 +1,4 @@ +cp server_private_files/settings.py . +cp server_private_files/helpers/ . -r +cp server_private_files/sbhs_admin_config.py . +cp server_private_files/tables/ . -r diff --git a/sbhs_server/map_machine_ids.txt b/sbhs_server/map_machine_ids.txt new file mode 100644 index 0000000..ceb2b7b --- /dev/null +++ b/sbhs_server/map_machine_ids.txt @@ -0,0 +1,30 @@ +15=/dev/ttyUSB31 +32=/dev/ttyUSB30 +20=/dev/ttyUSB29 +25=/dev/ttyUSB28 +28=/dev/ttyUSB26 +24=/dev/ttyUSB25 +22=/dev/ttyUSB24 +18=/dev/ttyUSB23 +27=/dev/ttyUSB22 +26=/dev/ttyUSB21 +30=/dev/ttyUSB20 +29=/dev/ttyUSB19 +11=/dev/ttyUSB18 +1=/dev/ttyUSB17 +8=/dev/ttyUSB16 +7=/dev/ttyUSB15 +3=/dev/ttyUSB14 +6=/dev/ttyUSB13 +2=/dev/ttyUSB12 +13=/dev/ttyUSB11 +14=/dev/ttyUSB10 +16=/dev/ttyUSB9 +21=/dev/ttyUSB7 +31=/dev/ttyUSB8 +19=/dev/ttyUSB6 +23=/dev/ttyUSB5 +10=/dev/ttyUSB4 +5=/dev/ttyUSB3 +12=/dev/ttyUSB2 +9=/dev/ttyUSB1 diff --git a/sbhs_server/pages/__init__.py b/sbhs_server/pages/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/pages/__init__.py diff --git a/sbhs_server/pages/__init__.pyc b/sbhs_server/pages/__init__.pyc Binary files differnew file mode 100644 index 0000000..f37f24c --- /dev/null +++ b/sbhs_server/pages/__init__.pyc diff --git a/sbhs_server/pages/admin.py b/sbhs_server/pages/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/pages/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/pages/management/__init__.py b/sbhs_server/pages/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/pages/management/__init__.py diff --git a/sbhs_server/pages/management/__init__.pyc b/sbhs_server/pages/management/__init__.pyc Binary files differnew file mode 100644 index 0000000..d400ccc --- /dev/null +++ b/sbhs_server/pages/management/__init__.pyc diff --git a/sbhs_server/pages/management/commands/__init__.py b/sbhs_server/pages/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/pages/management/commands/__init__.py diff --git a/sbhs_server/pages/management/commands/arm.diff b/sbhs_server/pages/management/commands/arm.diff new file mode 100644 index 0000000..868bec1 --- /dev/null +++ b/sbhs_server/pages/management/commands/arm.diff @@ -0,0 +1,14 @@ +--- a/sbhs_server/pages/management/commands/zip_client.py ++++ b/sbhs_server/pages/management/commands/zip_client.py +@@ -33,6 +33,10 @@ class Command(BaseCommand): + run_file_dirpath = os.path.join(dirpath, "run_file") + + os.mkdir(tmp_dirpath) ++ for root, dirs, files in os.walk(dirpath): ++ for f in files: ++ shutil.copy(os.path.join(dirpath, f), os.path.join(tmp_dirpath, f)) ++ + distutils.dir_util.copy_tree(scilab_codes_dirpath, tmp_dirpath) + try: + shutil.rmtree(tmp_dirpath + "/" + scilab_codes_dirname + "/.git") + diff --git a/sbhs_server/pages/management/commands/zip_client.py b/sbhs_server/pages/management/commands/zip_client.py new file mode 100644 index 0000000..89263bf --- /dev/null +++ b/sbhs_server/pages/management/commands/zip_client.py @@ -0,0 +1,66 @@ +from django.core.management.base import BaseCommand +import os, zipfile, shutil, distutils.core +from sbhs_server import settings + +class Command(BaseCommand): + args = '' + help = 'ZIP all clients for all architectures.' + + def handle(self, *args, **options): + def zipdir(path, zip, rootname): + for root, dirs, files in os.walk(path): + for file in files: + pathname = os.path.join(root, file) + zip.write(pathname, rootname + "/" + pathname.replace(path, "")) + + scilab_codes_dirname = "scilab_codes" + scilab_codes_dirpath = os.path.join(settings.SBHSCLIENT_STATIC_DIR, scilab_codes_dirname) + zipped_dirname = "zipped" + zipped_dirpath = os.path.join(settings.SBHSCLIENT_STATIC_DIR, zipped_dirname) + + dirs = os.listdir(settings.SBHSCLIENT_STATIC_DIR) + print dirs + dirs.remove(scilab_codes_dirname) + dirs.remove(zipped_dirname) + print dirs + dirs = [d for d in dirs if os.path.isdir(os.path.join(settings.SBHSCLIENT_STATIC_DIR, d))] + print dirs + dirs = [d for d in dirs if not d.startswith(".")] + + for dirname in dirs: + print dirname + dirpath = os.path.join(settings.SBHSCLIENT_STATIC_DIR, dirname) + tmp_dirpath = os.path.join(zipped_dirpath, dirname) + common_files_dirpath = os.path.join(dirpath, "common_files") + run_file_dirpath = os.path.join(dirpath, "run_file") + + os.mkdir(tmp_dirpath) + for f in os.listdir(dirpath): + if os.path.isfile(os.path.join(dirpath, f)): + shutil.copy(os.path.join(dirpath, f), os.path.join(tmp_dirpath, f)) + + if dirname not in ["analysis", "local"]: + distutils.dir_util.copy_tree(scilab_codes_dirpath, tmp_dirpath) + else: + distutils.dir_util.copy_tree(dirpath, tmp_dirpath) + try: + shutil.rmtree(tmp_dirpath + "/" + scilab_codes_dirname + "/.git") + except: + pass + + try: + for root, dirs, files in os.walk(tmp_dirpath): + if os.path.exists(os.path.join(root, "scilabread.sce")): + distutils.dir_util.copy_tree(run_file_dirpath, root) + except: + pass + + try: + distutils.dir_util.copy_tree(common_files_dirpath, os.path.join(tmp_dirpath, "common_files")) + except: + pass + + zipf = zipfile.ZipFile(os.path.join(zipped_dirpath, "sbhsclient/scilab_codes_" + dirname + ".zip"), 'w', zipfile.ZIP_DEFLATED) + zipdir(tmp_dirpath, zipf, "scilab_codes_" + dirname) + zipf.close() + shutil.rmtree(tmp_dirpath) diff --git a/sbhs_server/pages/models.py b/sbhs_server/pages/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/pages/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/pages/models.pyc b/sbhs_server/pages/models.pyc Binary files differnew file mode 100644 index 0000000..470724c --- /dev/null +++ b/sbhs_server/pages/models.pyc diff --git a/sbhs_server/pages/tests.py b/sbhs_server/pages/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/pages/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/pages/views.py b/sbhs_server/pages/views.py new file mode 100644 index 0000000..4b88086 --- /dev/null +++ b/sbhs_server/pages/views.py @@ -0,0 +1,41 @@ +from django.shortcuts import render +from django.template.loader import render_to_string +from django.http import HttpResponseNotFound, HttpResponseServerError + +# Create your views here. + +def index(req): + return render(req, "pages/index.html") + +def about(req): + return render(req, "pages/about.html") + +def contact(req): + return render(req, "pages/contact.html") + +def info(req): + return render(req, "pages/info.html") + +def downloads(req): + return render(req, "pages/downloads.html") + +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") + +def quiz(req): + return render(req, "pages/quiz.html") + +def e404(req): + return HttpResponseNotFound(render_to_string('pages/e404.html')) + +def e500(req): + return HttpResponseServerError(render_to_string('pages/e500.html')) diff --git a/sbhs_server/password/__init__.py b/sbhs_server/password/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/password/__init__.py diff --git a/sbhs_server/password/__init__.pyc b/sbhs_server/password/__init__.pyc Binary files differnew file mode 100644 index 0000000..31ad3f1 --- /dev/null +++ b/sbhs_server/password/__init__.pyc diff --git a/sbhs_server/password/admin.py b/sbhs_server/password/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/password/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/password/models.py b/sbhs_server/password/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/password/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/password/models.pyc b/sbhs_server/password/models.pyc Binary files differnew file mode 100644 index 0000000..d0a712d --- /dev/null +++ b/sbhs_server/password/models.pyc diff --git a/sbhs_server/password/tests.py b/sbhs_server/password/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/password/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/password/views.py b/sbhs_server/password/views.py new file mode 100644 index 0000000..6659998 --- /dev/null +++ b/sbhs_server/password/views.py @@ -0,0 +1,83 @@ +from django.shortcuts import render, redirect +from sbhs_server.tables.models import Account +from django.contrib import messages +from sbhs_server.helpers import simple_encrypt +from sbhs_server.pages.views import index as INDEX_PAGE +import datetime + +# Create your views here. + +def new(req): + return render(req, 'password/new.html') + +def password_token(username): + return simple_encrypt.encrypt(username + ",,," + str(datetime.datetime.now())) + +def email(req): + email = req.POST.get("email") + + account = Account.objects.filter(email=email) + + if len(account) == 1: + account[0].send_password_link(password_token(account[0].username)) + messages.add_message(req, messages.SUCCESS, "Password reset link has been sent to your email address.") + return redirect(INDEX_PAGE) + +def validate_token(req, token): + try: + data = simple_encrypt.decrypt(token) + except: + messages.add_message(req, messages.ERROR, "Invalid link") + return redirect(INDEX_PAGE), False + + data = data.split(",,,") + if len(data) != 2: + messages.add_message(req, messages.ERROR, "Invalid link") + return redirect(INDEX_PAGE), False + + return data, True + +def edit(req, token): + data, flag = validate_token(req, token) + if not flag: + return data + + timediff = datetime.datetime.now() - datetime.datetime.strptime(data[1], "%Y-%m-%d %H:%M:%S.%f") + + if timediff.total_seconds() < 7200: + return render(req, "password/edit.html", {"token": token}) + else: + messages.add_message(req, messages.ERROR, "The reset link is expired.") + return redirect(INDEX_PAGE) + +def update(req, token): + data, flag = validate_token(req, token) + if not flag: + return data + + timediff = datetime.datetime.now() - datetime.datetime.strptime(data[1], "%Y-%m-%d %H:%M:%S.%f") + + if timediff.total_seconds() < 7200: + username = data[0] + account = Account.objects.filter(username=username) + if len(account) == 1: + error = "" + if req.POST.get("email") != account[0].email: + error = "Invalid email" + if req.POST.get("password") != req.POST.get("confirm"): + error = "Passwords do not match" + + if error != "": + messages.add_message(req, messages.ERROR, error) + return redirect(INDEX_PAGE) + + account[0].set_password(req.POST.get("password")) + account[0].save() + messages.add_message(req, messages.SUCCESS, "Password changed successfully") + return redirect(INDEX_PAGE) + else: + messages.add_message(req, messages.ERROR, "Invalid link") + return redirect(INDEX_PAGE) + else: + messages.add_message(req, messages.ERROR, "The reset link is expired.") + return redirect(INDEX_PAGE)
\ No newline at end of file diff --git a/sbhs_server/sbhs.py b/sbhs_server/sbhs.py new file mode 100644 index 0000000..1cb9f52 --- /dev/null +++ b/sbhs_server/sbhs.py @@ -0,0 +1,206 @@ +import serial +import os +from time import localtime, strftime, sleep + +MAP_FILE = '/home/vlabs/sbhs_vlabs/sbhs/map_machine_ids.txt' +#LOG_FILE = '../log/sbhserr.log' +LOG_FILE = '/tmp/sbhserr.log' + +OUTGOING_MACHINE_ID = 252 +INCOMING_FAN = 253 +INCOMING_HEAT = 254 +OUTGOING_TEMP = 255 + +MAX_HEAT = 100 +MAX_FAN = 100 + +class Sbhs: + """ This is the Single Board Heater System class """ + + def __init__(self): + # status of the board + # 0 = not connected + # 1 = connected + self.machine_id = 26 + self.device_num = 26 + self.boardcon = False + self.status = 0 + + def connect(self, machine_id): + """ Open a serial connection via USB to the SBHS using the machine id """ + # check for valid machine id number + try: + self.machine_id = int(machine_id) + except: + #with open('error.txt', 'w') as errrr: + # errrr.write('Invalid machine id specified % d' % self.machine_id) + return False + + # get the usb device file from the machine map file + try: + map_file = open(MAP_FILE, 'r') + usb_device_file = False + for mapping_str in map_file.readlines(): + mapping = mapping_str.split('=') + self.log('mapping: ' + mapping[1], 'ERROR') #srikant + # if mapping for the machine id found set the usb device file and break out of loop + if mapping[0] == str(self.machine_id): + usb_device_file = mapping[1].strip() + #self.log('usb_device_file: ' + usb_device_file, 'ERROR') #srikant + break + # reached end of file and check if machine id entry is present in the machine map file + map_file.close() + if not usb_device_file: + print 'Error: cannot locate the USB device in the map table for machine id %d' % self.machine_id + self.log('cannot locate the USB device in the map table for machine id %d' % self.machine_id, 'ERROR') + return False + except: + # map_file.close() + print 'Error: cannot get the USB device path for the machine id %d' % self.machine_id + self.log('cannot get the USB device path for the machine id %d' % self.machine_id, 'ERROR') + return False + + # check if SBHS device is connected + if not os.path.exists(usb_device_file): + print 'SBHS device file ' + usb_device_file + ' does not exists' + self.log('SBHS device file ' + usb_device_file + ' does not exists', 'ERROR') + return False + try: + self.boardcon = serial.Serial(port=usb_device_file, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=2) #orignal stopbits = 1 + self.status = 1 + return True + except serial.serialutil.SerialException: + print 'Error: cannot connect to machine id %d' % self.machine_id + self.log('cannot connect to machine id %d' % self.machine_id, 'ERROR') + self.machine_id = -1 + self.device_num = -1 + self.boardcon = False + self.status = 0 + + def connect_device(self, device_num): + """ Open a serial connection via USB to the SBHS using USB Device Number""" + # check for valid device number + try: + self.device_num = int(device_num) + except: + print 'Invalid device number specified' + return False + + usb_device_file = '/dev/ttyUSB%d' % self.device_num + # check if SBHS device is connected + if not os.path.exists(usb_device_file): + print 'SBHS device file ' + usb_device_file + ' does not exists' + self.log('SBHS device file ' + usb_device_file + ' does not exists', 'ERROR') + return False + try: + self.boardcon = serial.Serial(port=usb_device_file, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=2) # org stopbits = 1 + self.machine_id = self.getMachineId() + if self.machine_id != -1: + return True + else: + print "Machine %s not responding. Check SBHS device!!" % usb_device_file + except: + print 'Error: cannot connect to device %s' % usb_device_file + self.log('cannot connect to device %s' % usb_device_file, 'ERROR') + return False + + def setHeat(self, val): + """ Set the heat """ + if val > MAX_HEAT or val < 0: + print 'Error: heat value cannot be more than %d' % MAX_HEAT + return False + + try: + self._write(chr(INCOMING_HEAT)) + self._write(chr(val)) + return True + except: + print 'Error: cannot set heat for machine id %d' % self.machine_id + self.log('cannot set heat for machine id %d' % self.machine_id, 'ERROR') + return False + + def setFan(self, val): + """ Set the fan """ + if val > MAX_FAN or val < 0: + print 'Error: fan value cannot be more than %d' % MAX_FAN + return False + try: + self._write(chr(INCOMING_FAN)) + self._write(chr(val)) + return True + except: + print 'Error: cannot set fan for machine id %d' % self.machine_id + self.log('cannot set fan for machine id %d' % self.machine_id, 'ERROR') + return False + + def getTemp(self): + """ Get the temperature """ + try: + self.boardcon.flushInput() + self._write(chr(OUTGOING_TEMP)) + temp = ord(self._read(1)) + (0.1 * ord(self._read(1))) + return temp + except: + print 'Error: cannot read temperature from machine id %d' % self.machine_id + self.log('cannot read temperature from machine id %d' % self.machine_id, 'ERROR') + return 0.0 + + def getMachineId(self): + """ Get machine id from the device """ + try: + self.boardcon.flushInput() + self._write(chr(OUTGOING_MACHINE_ID)) + sleep(0.5) + machine_id = ord(self._read(1)) + return machine_id + except: + print 'Error: cannot read machine id from %s' % self.boardcon.port + self.log('cannot read machine id from %s' % self.boardcon.port, 'ERROR') + return -1 + + def disconnect(self): + """ Reset the board fan and heat values and close the USB connection """ + try: + self.boardcon.close() + self.boardcon = False + self.status = 0 + return True + except: + print 'Error: cannot close connection to the machine' + self.log('cannot close connection to the machine', 'ERROR') + return False + + def reset_board(self): + self.setFan(100) + self.setHeat(0) + + def _read(self, size): + try: + data = self.boardcon.read(size) + return data + except: + print 'Error: cannot read from machine id %d' % self.machine_id + self.log('cannot read from machine id %d' % self.machine_id, 'ERROR') + raise Exception + + def _write(self, data): + try: + self.boardcon.write(data) + return True + except: + print 'Error: cannot write to machine id %d' % self.machine_id + self.log('cannot write to machine id %d' % self.machine_id, 'ERROR') + raise Exception + + def log(self, msg, level): + try: + errfile = open(LOG_FILE, 'a') # open error log file in append mode + if not errfile: + return + log_msg = '%s %s %s\n' %(level, strftime('%d:%m:%Y %H:%M:%S', localtime()), msg) + errfile.write(log_msg) + errfile.close() + return + except: + return + diff --git a/sbhs_server/sbhs.pyc b/sbhs_server/sbhs.pyc Binary files differnew file mode 100644 index 0000000..3a1dc42 --- /dev/null +++ b/sbhs_server/sbhs.pyc diff --git a/sbhs_server/sbhs_admin_config.py b/sbhs_server/sbhs_admin_config.py new file mode 100644 index 0000000..b046bab --- /dev/null +++ b/sbhs_server/sbhs_admin_config.py @@ -0,0 +1,5 @@ +SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9960633312", "amol.mandhane@gmail.com"), + ("Rupak Rokade", "+91-9960447251", "rupakrokade@gmail.com"), + ("Akshay Chipkar", "+91-9969188178", "akshaychipkar@gmail.com"), + ) diff --git a/sbhs_server/sbhs_admin_config.pyc b/sbhs_server/sbhs_admin_config.pyc Binary files differnew file mode 100644 index 0000000..2ab15bc --- /dev/null +++ b/sbhs_server/sbhs_admin_config.pyc diff --git a/sbhs_server/sbhserr.log b/sbhs_server/sbhserr.log new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/sbhserr.log diff --git a/sbhs_server/scan_machine1.py b/sbhs_server/scan_machine1.py new file mode 100644 index 0000000..f6922de --- /dev/null +++ b/sbhs_server/scan_machine1.py @@ -0,0 +1,85 @@ +#!/usb/bin/python +import sbhs +import os +import sys + +# erase the old map_machine_ids.txt file +try: + file('map_machine_ids.txt', 'w').close() +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# open the map_machine_ids file for writing +try: + map_machine_file = file('map_machine_ids.txt', 'w') +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# get list of device file names that start with ttyUSB* in the /dev folder +#device_files = [] +device_files = [each for each in os.listdir('/dev') if each.startswith('ttyUSB')] + +# if no device filename found then exit +if not device_files: + print 'No USB device found in /dev folder' + sys.exit(1) + +for device in device_files: + port_counter = 0 + mid_counter = 0 + s = sbhs.Sbhs() + # getting the number from the device filename + dev_id = device[6:] + print dev_id + try: + dev_id = int(dev_id) + except: + #res = False + print 'Invalid device name /dev/%s' % device + continue + # connect to device + res = s.connect_device(dev_id) + #print res + if not res: + print "Couldn't connect to the device on /dev/ttyUSB{0}. Retrying!!".format(dev_id) + for i in range(5): + res2 = s.connect_device(dev_id) + print "Trying!!! Attempt {0} for ttyUSB{1}".format(i, dev_id) + if res2 == True: + port_counter += 1 + if port_counter < 3: + print 'Cannot connect to /dev/%s.' % device + s.disconnect() + + for ii in range(1,6): + try: + machine_id = s.getMachineId() + print machine_id + except AttributeError: + machine_id = -1 + #machine_id = s.getMachineId() + if machine_id > 0: + mid_counter+=1 + + if mid_counter < 3: + print 'Cannot get machine id from /dev/%s' % device + s.disconnect() + continue + else: + print 'Found SBHS device /dev/%s with machine id %d' % (device, machine_id) + map_str = "%d=/dev/%s\n" % (machine_id, device) + map_machine_file.write(map_str) + + +print 'Done. Exiting...' +map_machine_file.close() +sys.exit(1) + + + + + + + diff --git a/sbhs_server/scan_machine1.py.save b/sbhs_server/scan_machine1.py.save new file mode 100644 index 0000000..608c1ab --- /dev/null +++ b/sbhs_server/scan_machine1.py.save @@ -0,0 +1,84 @@ +#!/usb/bin/python +import sbhs +import os +import sys + +# erase the old map_machine_ids.txt file +try: + file('map_machine_ids.txt', 'w').close() +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# open the map_machine_ids file for writing +try: + map_machine_file = file('map_machine_ids.txt', 'w') +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# get list of device file names that start with ttyUSB* in the /dev folder +#device_files = [] +device_files = [each for each in os.listdir('/dev') if each.startswith('ttyUSB')] + +# if no device filename found then exit +if not device_files: + print 'No USB device found in /dev folder' + sys.exit(1) + +for device in device_files: + port_counter = 0 + mid_counter = 0 + s = sbhs.Sbhs() + # getting the number from the device filename + dev_id = device[6:] + print dev_id + try: + dev_id = int(dev_id) + except: + #res = False + print 'Invalid device name /dev/%s' % device + continue + # connect to device + res = s.connect_device(dev_id) + #print res + if not res: + print "Couldn't connect to the device on /dev/ttyUSB{0}. Retrying!!".format(dev_id) + for i in range(1,6): + res2 = s.connect_device(dev_id) + print "Trying!!! Attempt {0} for ttyUSB{1}".format(i, dev_id) + if res2 == True: + port_counter += 1 + if port_counter < 3: + print 'Cannot connect to /dev/%s.' % device + s.disconnect() + + for ii in range(1,6): + try: + machine_id = s.getMachineId() + except AttributeError: + machine_id= -1 + #machine_id = s.getMachineId() + if machine_id != -1: + mid_counter+=1 + + if mid_counter < 3: + print 'Cannot get machine id from /dev/%s' % device + s.disconnect() + continue + else: + print 'Found SBHS device /dev/%s with machine id %d' % (device, machine_id) + map_str = "%d=/dev/%s\n" % (machine_id, device) + map_machine_file.write(map_str) + + +print 'Done. Exiting...' +map_machine_file.close() +sys.exit(1) + + + + + + + diff --git a/sbhs_server/scan_machines.py b/sbhs_server/scan_machines.py new file mode 100644 index 0000000..2548941 --- /dev/null +++ b/sbhs_server/scan_machines.py @@ -0,0 +1,58 @@ +#!/usb/bin/python +import sbhs +import os +import sys + +# erase the old map_machine_ids.txt file +try: + file('map_machine_ids.txt', 'w').close() +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# open the map_machine_ids file for writing +try: + map_machine_file = file('map_machine_ids.txt', 'w') +except: + print 'Failed to create machine map file file' + sys.exit(1) + +# get list of device file names that start with ttyUSB* in the /dev folder +#device_files = [] +device_files = [each for each in os.listdir('/dev') if each.startswith('ttyUSB')] +print device_files + +# if no device filename found then exit +if not device_files: + print 'No USB device found in /dev folder' + sys.exit(1) + +for device in device_files: + s = sbhs.Sbhs() + # getting the number from the device filename + dev_id = device[6:] + try: + dev_id = int(dev_id) + except: + print 'Invalid device name /dev/%s' % device + continue + # connect to device + res = s.connect_device(dev_id) + if not res: + print 'Cannot connect to /dev/%s' % device + s.disconnect() + continue + # get the machine id from the device + machine_id = s.getMachineId() + if machine_id < 0: + print 'Cannot get machine id from /dev/%s' % device + s.disconnect() + continue + print 'Found SBHS device /dev/%s with machine id %d' % (device, machine_id) + map_str = "%d=/dev/%s\n" % (machine_id, device) + map_machine_file.write(map_str) + +print 'Done. Exiting...' +map_machine_file.close() +sys.exit(1) + diff --git a/sbhs_server/server_private_files b/sbhs_server/server_private_files new file mode 160000 +Subproject 015354ba06771085a493cfffaa93576f8e1d5ac diff --git a/sbhs_server/settings.py b/sbhs_server/settings.py new file mode 100644 index 0000000..30a0f81 --- /dev/null +++ b/sbhs_server/settings.py @@ -0,0 +1,241 @@ +""" +Django settings for sbhs_server project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" +import sys #srikant +import socket +hostname = socket.gethostname() +is_production = hostname == "vlabs-Veriton-Series" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = is_production + +TEMPLATE_DEBUG = not is_production + +ALLOWED_HOSTS = [] + +if not DEBUG: + ALLOWED_HOSTS = [ + "localhost", + "127.0.0.1", + "vlabs.iitb.ac.in", + "vlabs.iitb.ac.in.", + "10.102.152.15", + ] + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + #'south', + 'undelete', + 'yaksh', + 'taggit', + + 'sbhs_server.account', + 'sbhs_server.admin', + 'sbhs_server.experiment', + 'sbhs_server.pages', + 'sbhs_server.password', + 'sbhs_server.slot', + 'sbhs_server.tables', + 'sbhs_server.webcam', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'sbhs_server.urls' + +WSGI_APPLICATION = 'sbhs_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +if is_production: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'database_name', + 'USER': 'username', + 'PASSWORD': 'password', + 'HOST': 'localhost', + 'PORT': '3306', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'sbhs.sqlite3'), + } + } + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +AUTH_USER_MODEL = 'tables.Account' +LOGIN_URL = '/sbhs/enter' +LOGOUT_URL = '/sbhs/logout' +SESSION_EXPIRE_AT_BROWSER_CLOSE = True +CSRF_COOKIE_NAME = "pfesgbxra" +SESSION_COOKIE_NAME = "frffvbaVq" + +EMAIL_HOST = 'smtp-auth.iitb.ac.in' +EMAIL_PORT = 25 +EMAIL_HOST_USER = "username" +EMAIL_HOST_PASSWORD = "password" + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + + +if is_production: + BASE_URL = "http://vlabs.iitb.ac.in/sbhs/" + FORCE_SCRIPT_NAME = "/sbhs" + USE_X_FORWARDED_HOST = True +else: + BASE_URL = "http://127.0.0.1:8000/" + +SBHSCLIENT_STATIC_DIR = os.path.join(BASE_DIR, "client_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "static"), + os.path.join(SBHSCLIENT_STATIC_DIR, "zipped"), +) + +if is_production: + STATIC_ROOT = os.path.join(BASE_DIR, "production_static_files") + STATIC_URL = 'http://vlabs.iitb.ac.in/sbhs/static/' +else: + STATIC_URL = '/static/' + +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'templates/'), +) + + +import warnings +warnings.filterwarnings( + 'ignore', r"DateTimeField .* received a naive datetime", + RuntimeWarning, r'django\.db\.models\.fields') + +if not is_production: + import logging + l = logging.getLogger('django.db') + l.setLevel(logging.DEBUG) + l.addHandler(logging.StreamHandler()) + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django.db': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + } + } +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'log/django_error.log'), + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['file'], + 'level': 'ERROR', + 'propagate': True, + } + } + } + +EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments') +WEBCAM_DIR = os.path.join(STATIC_ROOT, 'img/webcam/') if is_production else os.path.join(BASE_DIR, 'static/img/webcam/') +WEBCAM_STATIC_DIR = 'img/webcam/' + +if not is_production: + SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9999999999", "amol_mandhane@iitb.ac.in"), + ("Amol Mandhane", "+91-9999999999", "amol_mandhane@iitb.ac.in"), + ) +else: + from sbhs_server.sbhs_admin_config import SBHS_ADMINS + +SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log') + +from sbhs_server import sbhs +boards = {} +with open(os.path.join(BASE_DIR, 'map_machine_ids.txt')) as f: + for line in f: + try: + data = line.split("=") + brd = sbhs.Sbhs() + b = brd.connect(int(data[0])) + assert b == True + key = int(brd.getMachineId()) + assert key > 0 + brd.reset_board() + boards[str(key)] = {"board": brd, "experiment_id": None} + except: + pass + +online_mids = [int(i) for i in boards.keys()] + +import sys +print >>sys.stderr, online_mids[1:33] #srikant +#srikant +#f = open('/tmp/online_mids', 'w') +#f.write(online_mids) +#f.close() diff --git a/sbhs_server/settings.py.save b/sbhs_server/settings.py.save new file mode 100644 index 0000000..be7ae1b --- /dev/null +++ b/sbhs_server/settings.py.save @@ -0,0 +1,232 @@ +""" +Django settings for sbhs_server project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" + +import socket +hostname = socket.gethostname() +is_production = hostname == "vlabs-Veriton-Series" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '_5d&r^gt$!)p3(45uh1ulha05!b&ov)=waic8e2vwlh6549q7u=@f(' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = not is_production + +TEMPLATE_DEBUG = not is_production + +ALLOWED_HOSTS = [] + +if not DEBUG: + ALLOWED_HOSTS = [ + "localhost", + "127.0.0.1", + "vlabs.iitb.ac.in", + "vlabs.iitb.ac.in.", + "10.102.152.15", + ] + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'south', + 'undelete', + + 'sbhs_server.account', + 'sbhs_server.admin', + 'sbhs_server.experiment', + 'sbhs_server.pages', + 'sbhs_server.password', + 'sbhs_server.slot', + 'sbhs_server.tables', + 'sbhs_server.webcam', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'sbhs_server.urls' + +WSGI_APPLICATION = 'sbhs_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +if is_production: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'vlabs_sbhs', + 'USER': 'vlabs_sbhs', + 'PASSWORD': 'DJANGO4229', + 'HOST': 'localhost', + 'PORT': '3306', + } + } +#else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'sbhs.sqlite3'), + } + } + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +AUTH_USER_MODEL = 'tables.Account' +LOGIN_URL = '/sbhs/enter' +LOGOUT_URL = '/sbhs/logout' +SESSION_EXPIRE_AT_BROWSER_CLOSE = True +CSRF_COOKIE_NAME = "pfesgbxra" +SESSION_COOKIE_NAME = "frffvbaVq" + +EMAIL_HOST = 'smtp-auth.iitb.ac.in' +EMAIL_PORT = 25 +EMAIL_HOST_USER = "rupakrokade" +EMAIL_HOST_PASSWORD = "*rupak*iit" + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + + +if is_production: + BASE_URL = "http://vlabs.iitb.ac.in/sbhs/" + FORCE_SCRIPT_NAME = "/sbhs" + USE_X_FORWARDED_HOST = True +else: + BASE_URL = "http://127.0.0.1:8000/" + +SBHSCLIENT_STATIC_DIR = os.path.join(BASE_DIR, "client_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "static"), + os.path.join(SBHSCLIENT_STATIC_DIR, "zipped"), +) + +if is_production: + STATIC_ROOT = os.path.join(BASE_DIR, "production_static_files") + STATIC_URL = 'http://vlabs.iitb.ac.in/sbhs/static/' +else: + STATIC_URL = '/static/' + +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'templates/'), +) + + +import warnings +warnings.filterwarnings( + 'ignore', r"DateTimeField .* received a naive datetime", + RuntimeWarning, r'django\.db\.models\.fields') + +if not is_production: + import logging + l = logging.getLogger('django.db') + l.setLevel(logging.DEBUG) + l.addHandler(logging.StreamHandler()) + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django.db': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + } + } +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'log/django_error.log'), + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['file'], + 'level': 'ERROR', + 'propagate': True, + } + } + } + +EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments') +WEBCAM_DIR = os.path.join(STATIC_ROOT, 'img/webcam/') if is_production else os.path.join(BASE_DIR, 'static/img/webcam/') +WEBCAM_STATIC_DIR = 'img/webcam/' + +if not is_production: + SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ) +else: + from sbhs_server.sbhs_admin_config import SBHS_ADMINS + +SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log') + +from sbhs_server import sbhs +boards = {} +with open(os.path.join(BASE_DIR, 'map_machine_ids.txt')) as f: + for line in f: + try: + data = line.split("=") + brd = sbhs.Sbhs() + b = brd.connect(int(data[0])) + assert b == True + key = int(brd.getMachineId()) + assert key > 0 + brd.reset_board() + boards[str(key)] = {"board": brd, "experiment_id": None} + except: + pass + +online_mids = [int(i) for i in boards.keys()] diff --git a/sbhs_server/settings.py.save.1 b/sbhs_server/settings.py.save.1 new file mode 100644 index 0000000..3e1f241 --- /dev/null +++ b/sbhs_server/settings.py.save.1 @@ -0,0 +1,234 @@ +""" +Django settings for sbhs_server project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" + +import socket +hostname = socket.gethostname() +is_production = hostname == "vlabs-Veriton-Series" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '_5d&r^gt$!)p3(45uh1ulha05!b&ov)=waic8e2vwlh6549q7u=@f(' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = is_production + +TEMPLATE_DEBUG = not is_production + +ALLOWED_HOSTS = [] + +if not DEBUG: + ALLOWED_HOSTS = [ + "localhost", + "127.0.0.1", + "vlabs.iitb.ac.in", + "vlabs.iitb.ac.in.", + "10.102.152.15", + ] + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'south', + 'undelete', + + 'sbhs_server.account', + 'sbhs_server.admin', + 'sbhs_server.experiment', + 'sbhs_server.pages', + 'sbhs_server.password', + 'sbhs_server.slot', + 'sbhs_server.tables', + 'sbhs_server.webcam', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'sbhs_server.urls' + +WSGI_APPLICATION = 'sbhs_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +if is_production: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'vlabs_sbhs', + 'USER': 'vlabs_sbhs', + 'PASSWORD': 'DJANGO4229', + 'HOST': 'localhost', + 'PORT': '3306', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'sbhs.sqlite3'), + } + } + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +AUTH_USER_MODEL = 'tables.Account' +LOGIN_URL = '/sbhs/enter' +LOGOUT_URL = '/sbhs/logout' +SESSION_EXPIRE_AT_BROWSER_CLOSE = True +CSRF_COOKIE_NAME = "pfesgbxra" +SESSION_COOKIE_NAME = "frffvbaVq" + +EMAIL_HOST = 'smtp-auth.iitb.ac.in' +EMAIL_PORT = 25 +EMAIL_HOST_USER = "rupakrokade" +EMAIL_HOST_PASSWORD = "*rupak*iit" + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + + +if is_production: + BASE_URL = "http://vlabs.iitb.ac.in/sbhs/" + FORCE_SCRIPT_NAME = "/sbhs" + USE_X_FORWARDED_HOST = True +else: + BASE_URL = "http://127.0.0.1:8000/" + +SBHSCLIENT_STATIC_DIR = os.path.join(BASE_DIR, "client_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "static"), + os.path.join(SBHSCLIENT_STATIC_DIR, "zipped"), +) + +if is_production: + STATIC_ROOT = os.path.join(BASE_DIR, "production_static_files") + STATIC_URL = 'http://vlabs.iitb.ac.in/sbhs/static/' +else: + STATIC_URL = '/static/' + +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'templates/'), +) + + +import warnings +warnings.filterwarnings( + 'ignore', r"DateTimeField .* received a naive datetime", + RuntimeWarning, r'django\.db\.models\.fields') + +if not is_production: + import logging + l = logging.getLogger('django.db') + l.setLevel(logging.DEBUG) + l.addHandler(logging.StreamHandler()) + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django.db': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + } + } +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'log/django_error.log'), + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['file'], + 'level': 'ERROR', + 'propagate': True, + } + } + } + +EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments') +WEBCAM_DIR = os.path.join(STATIC_ROOT, 'img/webcam/') if is_production else os.path.join(BASE_DIR, 'static/img/webcam/') +WEBCAM_STATIC_DIR = 'img/webcam/' + +if not is_production: + SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ) +else: + from sbhs_server.sbhs_admin_config import SBHS_ADMINS + +SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log') + +from sbhs_server import sbhs +boards = {} +with open(os.path.join(BASE_DIR, 'map_machine_ids.txt')) as f: + for line in f: + try: + data = line.split("=") + brd = sbhs.Sbhs() + b = brd.connect(int(data[0])) + assert b == True + key = int(brd.getMachineId()) + assert key > 0 + brd.reset_board() + boards[str(key)] = {"board": brd, "experiment_id": None} + except: + pass + +online_mids = [int(i) for i in boards.keys()] + + diff --git a/sbhs_server/settings.py.save.2 b/sbhs_server/settings.py.save.2 new file mode 100644 index 0000000..e7fe611 --- /dev/null +++ b/sbhs_server/settings.py.save.2 @@ -0,0 +1,232 @@ +""" +Django settings for sbhs_server project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" + +import socket +hostname = socket.gethostname() +is_production = hostname == "vlabs-Veriton-Series" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '_5d&r^gt$!)p3(45uh1ulha05!b&ov)=waic8e2vwlh6549q7u=@f(' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = is_production + +TEMPLATE_DEBUG = not is_production + +ALLOWED_HOSTS = [] + +if not DEBUG: + ALLOWED_HOSTS = [ + "localhost", + "127.0.0.1", + "vlabs.iitb.ac.in", + "vlabs.iitb.ac.in.", + "10.102.152.15", + ] + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'south', + 'undelete', + + 'sbhs_server.account', + 'sbhs_server.admin', + 'sbhs_server.experiment', + 'sbhs_server.pages', + 'sbhs_server.password', + 'sbhs_server.slot', + 'sbhs_server.tables', + 'sbhs_server.webcam', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'sbhs_server.urls' + +WSGI_APPLICATION = 'sbhs_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +if is_production: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'vlabs_sbhs', + 'USER': 'vlabs_sbhs', + 'PASSWORD': 'DJANGO4229', + 'HOST': 'localhost', + 'PORT': '3306', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'sbhs.sqlite3'), + } + } + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +AUTH_USER_MODEL = 'tables.Account' +LOGIN_URL = '/sbhs/enter' +LOGOUT_URL = '/sbhs/logout' +SESSION_EXPIRE_AT_BROWSER_CLOSE = True +CSRF_COOKIE_NAME = "pfesgbxra" +SESSION_COOKIE_NAME = "frffvbaVq" + +EMAIL_HOST = 'smtp-auth.iitb.ac.in' +EMAIL_PORT = 25 +EMAIL_HOST_USER = "rupakrokade" +EMAIL_HOST_PASSWORD = "*rupak*iit" + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + + +if is_production: + BASE_URL = "http://vlabs.iitb.ac.in/sbhs/" + FORCE_SCRIPT_NAME = "/sbhs" + USE_X_FORWARDED_HOST = True +else: + BASE_URL = "http://127.0.0.1:8000/" + +SBHSCLIENT_STATIC_DIR = os.path.join(BASE_DIR, "client_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "static"), + os.path.join(SBHSCLIENT_STATIC_DIR, "zipped"), +) + +if is_production: + STATIC_ROOT = os.path.join(BASE_DIR, "production_static_files") + STATIC_URL = 'http://vlabs.iitb.ac.in/sbhs/static/' +else: + STATIC_URL = '/static/' + +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'templates/'), +) + + +import warnings +warnings.filterwarnings( + 'ignore', r"DateTimeField .* received a naive datetime", + RuntimeWarning, r'django\.db\.models\.fields') + +if not is_production: + import logging + l = logging.getLogger('django.db') + l.setLevel(logging.DEBUG) + l.addHandler(logging.StreamHandler()) + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django.db': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + } + } +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'log/django_error.log'), + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['file'], + 'level': 'ERROR', + 'propagate': True, + } + } + } + +EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments') +WEBCAM_DIR = os.path.join(STATIC_ROOT, 'img/webcam/') if is_production else os.path.join(BASE_DIR, 'static/img/webcam/') +WEBCAM_STATIC_DIR = 'img/webcam/' + +if not is_production: + SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ) +else: + from sbhs_server.sbhs_admin_config import SBHS_ADMINS + +SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log') + +from sbhs_server import sbhs +boards = {} +with open(os.path.join(BASE_DIR, 'map_machine_ids.txt')) as f: + for line in f: + try: + data = line.split("=") + brd = sbhs.Sbhs() + b = brd.connect(int(data[0])) + assert b == True + key = int(brd.getMachineId()) + assert key > 0 + brd.reset_board() + boards[str(key)] = {"board": brd, "experiment_id": None} + except: + pass + +online_mids = [int(i) for i in boards.keys()] diff --git a/sbhs_server/settings.py.save.3 b/sbhs_server/settings.py.save.3 new file mode 100644 index 0000000..170e7d9 --- /dev/null +++ b/sbhs_server/settings.py.save.3 @@ -0,0 +1,233 @@ +""" +Django settings for sbhs_server project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" + +import socket +hostname = socket.gethostname() +is_production = hostname == "vlabs-Veriton-Series" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '_5d&r^gt$!)p3(45uh1ulha05!b&ov)=waic8e2vwlh6549q7u=@f(' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = is_production + +TEMPLATE_DEBUG = not is_production + +ALLOWED_HOSTS = [] + +if not DEBUG: + ALLOWED_HOSTS = [ + "localhost", + "127.0.0.1", + "vlabs.iitb.ac.in", + "vlabs.iitb.ac.in.", + "10.102.152.15", + ] + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'south', + 'undelete', + + 'sbhs_server.account', + 'sbhs_server.admin', + 'sbhs_server.experiment', + 'sbhs_server.pages', + 'sbhs_server.password', + 'sbhs_server.slot', + 'sbhs_server.tables', + 'sbhs_server.webcam', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'sbhs_server.urls' + +WSGI_APPLICATION = 'sbhs_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +if is_production: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'vlabs_sbhs', + 'USER': 'vlabs_sbhs', + 'PASSWORD': 'DJANGO4229', + 'HOST': 'localhost', + 'PORT': '3306', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'sbhs.sqlite3'), + } + } + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +AUTH_USER_MODEL = 'tables.Account' +LOGIN_URL = '/sbhs/enter' +LOGOUT_URL = '/sbhs/logout' +SESSION_EXPIRE_AT_BROWSER_CLOSE = True +CSRF_COOKIE_NAME = "pfesgbxra" +SESSION_COOKIE_NAME = "frffvbaVq" + +EMAIL_HOST = 'smtp-auth.iitb.ac.in' +EMAIL_PORT = 25 +EMAIL_HOST_USER = "rupakrokade" +EMAIL_HOST_PASSWORD = "*rupak*iit" + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + + +if is_production: + BASE_URL = "http://vlabs.iitb.ac.in/sbhs/" + FORCE_SCRIPT_NAME = "/sbhs" + USE_X_FORWARDED_HOST = True +else: + BASE_URL = "http://127.0.0.1:8000/" + +SBHSCLIENT_STATIC_DIR = os.path.join(BASE_DIR, "client_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "static"), + os.path.join(SBHSCLIENT_STATIC_DIR, "zipped"), +) + +if is_production: + STATIC_ROOT = os.path.join(BASE_DIR, "production_static_files") + STATIC_URL = 'http://vlabs.iitb.ac.in/sbhs/static/' +else: + STATIC_URL = '/static/' + +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'templates/'), +) + + +import warnings +warnings.filterwarnings( + 'ignore', r"DateTimeField .* received a naive datetime", + RuntimeWarning, r'django\.db\.models\.fields') + +if not is_production: + import logging + l = logging.getLogger('django.db') + l.setLevel(logging.DEBUG) + l.addHandler(logging.StreamHandler()) + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django.db': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + } + } +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'log/django_error.log'), + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['file'], + 'level': 'ERROR', + 'propagate': True, + } + } + } + +EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments') +WEBCAM_DIR = os.path.join(STATIC_ROOT, 'img/webcam/') if is_production else os.path.join(BASE_DIR, 'static/img/webcam/') +WEBCAM_STATIC_DIR = 'img/webcam/' + +if not is_production: + SBHS_ADMINS = ( + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ("Amol Mandhane", "+91-9960633312", "amol_mandhane@iitb.ac.in"), + ) +else: + from sbhs_server.sbhs_admin_config import SBHS_ADMINS + +SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log') + +from sbhs_server import sbhs +boards = {} +with open(os.path.join(BASE_DIR, 'map_machine_ids.txt')) as f: + for line in f: + try: + data = line.split("=") + brd = sbhs.Sbhs() + b = brd.connect(int(data[0]))\ + assert b == True + key = int(brd.getMachineId()) + assert key > 0 + brd.reset_board() + boards[str(key)] = {"board": brd, "experiment_id": None} + except: + pass + +online_mids = [int(i) for i in boards.keys()] + diff --git a/sbhs_server/settings.pyc b/sbhs_server/settings.pyc Binary files differnew file mode 100644 index 0000000..92c8db9 --- /dev/null +++ b/sbhs_server/settings.pyc diff --git a/sbhs_server/slot/__init__.py b/sbhs_server/slot/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/slot/__init__.py diff --git a/sbhs_server/slot/__init__.pyc b/sbhs_server/slot/__init__.pyc Binary files differnew file mode 100644 index 0000000..0f4e397 --- /dev/null +++ b/sbhs_server/slot/__init__.pyc diff --git a/sbhs_server/slot/admin.py b/sbhs_server/slot/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/slot/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/slot/migrations/0001_slot_timing_data.py b/sbhs_server/slot/migrations/0001_slot_timing_data.py new file mode 100644 index 0000000..158f201 --- /dev/null +++ b/sbhs_server/slot/migrations/0001_slot_timing_data.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models +from sbhs_server.tables.models import Slot + +class Migration(DataMigration): + + def forwards(self, orm): + # "Write your forwards methods here." + # Note: Don't use "from appname.models import ModelName". + # Use orm.ModelName to refer to models in this application, + # and orm['appname.ModelName'] for models in other applications. + for i in xrange(24): + Slot.objects.create(start_hour=i, end_hour=i, start_minute=0, end_minute=55) + + def backwards(self, orm): + # "Write your backwards methods here." + for i in xrange(24): + Slot.objects.delete(i) + + + models = { + + } + + complete_apps = ['slot'] + symmetrical = True diff --git a/sbhs_server/slot/migrations/__init__.py b/sbhs_server/slot/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/slot/migrations/__init__.py diff --git a/sbhs_server/slot/models.py b/sbhs_server/slot/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/slot/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/slot/models.pyc b/sbhs_server/slot/models.pyc Binary files differnew file mode 100644 index 0000000..2f7dc8d --- /dev/null +++ b/sbhs_server/slot/models.pyc diff --git a/sbhs_server/slot/tests.py b/sbhs_server/slot/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/slot/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/slot/views.py b/sbhs_server/slot/views.py new file mode 100644 index 0000000..b137f93 --- /dev/null +++ b/sbhs_server/slot/views.py @@ -0,0 +1,76 @@ +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, redirect +from django.contrib import messages +from sbhs_server.tables.models import Account, Slot, Booking +import datetime + +LIMIT = 2 + +@login_required(redirect_field_name=None) +def new(req): + cur_slots = Slot.current_slots(req.user.board.mid) + all_slots = Slot.get_free_slots(req.user.board.mid) + date = (datetime.datetime.now()).strftime("%Y-%m-%d") + return render(req, "slot/new.html", {"all_slots": all_slots, "cur_slots": cur_slots, "nowdate": date}) + +@login_required(redirect_field_name=None) +def show(req, date_string): + date = datetime.datetime.strptime(date_string, "%Y-%m-%d") + all_slots = Slot.get_free_slots_on(date, req.user.board.mid) + return render(req, "slot/show.html", {"all_slots": all_slots}) + +@login_required(redirect_field_name=None) +def create(req): + slot = Slot.objects.get(id=req.POST.get("slot")) + date_string = req.POST.get("date") + date = datetime.date.today() if date_string == "CURRENT" else datetime.datetime.strptime(date_string, "%Y-%m-%d") + all_slots = Slot.get_free_slots(req.user.board.mid) if date_string == "CURRENT" else Slot.get_free_slots_on(date, req.user.board.mid) + + if slot in all_slots: + if date_string == "CURRENT": + Booking.objects.create(slot=slot, account=req.user, booking_date=date) + messages.add_message(req, messages.SUCCESS, "Slot " + str(slot) + " booked successfully.") + else: + bookings = req.user.booking_set.select_related("slot").filter(booking_date__year=date.year, + booking_date__month=date.month, + booking_date__day=date.day) + if len(bookings) >= LIMIT: + messages.add_message(req, messages.ERROR, "Can't book more than " + str(LIMIT) + " slots in a day in advance.") + elif len(bookings) < LIMIT: + consecutive_check = True + for b in bookings: + if abs(b.slot.start_hour - slot.start_hour) <= 1: + consecutive_check = False + break + if not consecutive_check: + messages.add_message(req, messages.ERROR, "Can't book 2 consecutive slots in a day in advance.") + else: + Booking.objects.create(slot=slot, account=req.user, booking_date=date) + messages.add_message(req, messages.SUCCESS, "Slot " + str(slot) + " booked successfully.") + else: + messages.add_message(req, messages.ERROR, "Slot " + str(slot) + " already booked.") + + return redirect(index) + +@login_required(redirect_field_name=None) +def index(req): + bookings = req.user.booking_set.select_related("slot").order_by("booking_date") + + return render(req, "slot/index.html", {"bookings": reversed(bookings), + "now_time": datetime.datetime.now()}) + + +@login_required(redirect_field_name=None) +def delete(req, booking_id): + try: + booking = Booking.objects.select_related("slot").get(id=booking_id) + assert booking.account_id == req.user.id + if booking.start_time() > datetime.datetime.now(): + booking.delete() + messages.add_message(req, messages.SUCCESS, "Slot booking deleted successfully.") + else: + messages.add_message(req, messages.ERROR, "Slot time is over. Cannot delete this booking now.") + except: + messages.add_message(req, messages.ERROR, "Booking does not exist.") + + return redirect(index) diff --git a/sbhs_server/tables/__init__.py b/sbhs_server/tables/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/tables/__init__.py diff --git a/sbhs_server/tables/__init__.pyc b/sbhs_server/tables/__init__.pyc Binary files differnew file mode 100644 index 0000000..3b42411 --- /dev/null +++ b/sbhs_server/tables/__init__.pyc diff --git a/sbhs_server/tables/admin.py b/sbhs_server/tables/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/tables/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/tables/management/__init__.py b/sbhs_server/tables/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/tables/management/__init__.py diff --git a/sbhs_server/tables/management/__init__.pyc b/sbhs_server/tables/management/__init__.pyc Binary files differnew file mode 100644 index 0000000..409acc5 --- /dev/null +++ b/sbhs_server/tables/management/__init__.pyc diff --git a/sbhs_server/tables/management/commands/__init__.py b/sbhs_server/tables/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/tables/management/commands/__init__.py diff --git a/sbhs_server/tables/management/commands/__init__.pyc b/sbhs_server/tables/management/commands/__init__.pyc Binary files differnew file mode 100644 index 0000000..2bcdd35 --- /dev/null +++ b/sbhs_server/tables/management/commands/__init__.pyc diff --git a/sbhs_server/tables/management/commands/generate_checksum.py b/sbhs_server/tables/management/commands/generate_checksum.py new file mode 100644 index 0000000..5e708f0 --- /dev/null +++ b/sbhs_server/tables/management/commands/generate_checksum.py @@ -0,0 +1,33 @@ +from django.core.management.base import BaseCommand +from sbhs_server.tables.models import Experiment +import hashlib + +class Command(BaseCommand): + args = '' + help = 'Calculates checksum for unchecked experiments' + + def handle(self, *args, **options): + experiments = Experiment.objects.filter(checksum="NONE") + + for e in experiments: + try: + f = open(e.log, "r") + # If log file doesn't exist, it means experiment is not done yet. + # This takes care of that. + except: + return + + data = f.read() + f.close() + 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() + + e.checksum = checksum + e.save() + print checksum diff --git a/sbhs_server/tables/management/commands/generate_checksum.pyc b/sbhs_server/tables/management/commands/generate_checksum.pyc Binary files differnew file mode 100644 index 0000000..36d45a7 --- /dev/null +++ b/sbhs_server/tables/management/commands/generate_checksum.pyc diff --git a/sbhs_server/tables/management/commands/initialize_machines.py b/sbhs_server/tables/management/commands/initialize_machines.py new file mode 100644 index 0000000..1987a27 --- /dev/null +++ b/sbhs_server/tables/management/commands/initialize_machines.py @@ -0,0 +1,45 @@ +from django.core.management.base import BaseCommand, CommandError +from sbhs_server import settings +from sbhs_server.tables.models import Board +from sbhs_server import helpers + +class Command(BaseCommand): + args = '' + help = 'Initializes the SBHS board data in the database' + + def handle(self, *args, **options): + previous_onlines = Board.objects.only("mid").filter(online=True) + previous_onlines = [p.mid for p in previous_onlines] + for o in settings.online_mids: + try: + Board.objects.get_or_create(mid=o) + except: + pass + + new_offlines = [] + for p in previous_onlines: + if p not in settings.online_mids: + new_offlines.append(p) + + message = "SBHS Administrator,\n\n" + message += "Following issue requires immidiate attention.\n\n" + message += "SBHS could not be connected\n" + for n in new_offlines: + message += ("MID: %d\n" % n) + message += "\nYou can check the SBHS status on http://vlabs.iitb.ac.in/sbhs/admin/." + message += " Possible correction actions are:\n" + message += "1. Run this command without brackets -> ( cd $SBHS_SERVER_ROOT; ./cron_job.sh )\n" + message += "2. If same machine comes offline multiple times, replacement of the machine is advised.\n\n\n" + message += "Regards,\nSBHS Vlabs Server Code" + + print "New offline board mids", new_offlines + subject = "SBHS Vlabs: Notice - SBHS not connected" + + if len(new_offlines) > 0: + for admin in settings.SBHS_ADMINS: + helpers.mailer.email(admin[2], subject, message) + + Board.objects.filter(mid__in=settings.online_mids).update(online=True) + Board.objects.exclude(mid__in=settings.online_mids).update(online=False) + + self.stdout.write('Boards loaded') diff --git a/sbhs_server/tables/management/commands/initialize_machines.pyc b/sbhs_server/tables/management/commands/initialize_machines.pyc Binary files differnew file mode 100644 index 0000000..cbbb123 --- /dev/null +++ b/sbhs_server/tables/management/commands/initialize_machines.pyc diff --git a/sbhs_server/tables/migrations/0001_initial.py b/sbhs_server/tables/migrations/0001_initial.py new file mode 100644 index 0000000..b6de197 --- /dev/null +++ b/sbhs_server/tables/migrations/0001_initial.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Board' + db.create_table(u'tables_board', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('mid', self.gf('django.db.models.fields.IntegerField')(unique=True)), + ('online', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal(u'tables', ['Board']) + + # Adding model 'Account' + db.create_table(u'tables_account', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('password', self.gf('django.db.models.fields.CharField')(max_length=128)), + ('last_login', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('username', self.gf('django.db.models.fields.CharField')(unique=True, max_length=127)), + ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=255)), + ('is_active', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('is_admin', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('board', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['tables.Board'])), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal(u'tables', ['Account']) + + # Adding model 'Slot' + db.create_table(u'tables_slot', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('start_hour', self.gf('django.db.models.fields.IntegerField')()), + ('start_minute', self.gf('django.db.models.fields.IntegerField')()), + ('end_hour', self.gf('django.db.models.fields.IntegerField')()), + ('end_minute', self.gf('django.db.models.fields.IntegerField')()), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal(u'tables', ['Slot']) + + # Adding model 'Booking' + db.create_table(u'tables_booking', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('account', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['tables.Account'])), + ('slot', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['tables.Slot'])), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal(u'tables', ['Booking']) + + # Adding model 'Experiment' + db.create_table(u'tables_experiment', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('booking', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['tables.Booking'])), + ('log', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('checksum', self.gf('django.db.models.fields.CharField')(max_length=127)), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal(u'tables', ['Experiment']) + + + def backwards(self, orm): + # Deleting model 'Board' + db.delete_table(u'tables_board') + + # Deleting model 'Account' + db.delete_table(u'tables_account') + + # Deleting model 'Slot' + db.delete_table(u'tables_slot') + + # Deleting model 'Booking' + db.delete_table(u'tables_booking') + + # Deleting model 'Experiment' + db.delete_table(u'tables_experiment') + + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'checksum': ('django.db.models.fields.CharField', [], {'max_length': '127'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/0002_remove_experiment_checksum.py b/sbhs_server/tables/migrations/0002_remove_experiment_checksum.py new file mode 100644 index 0000000..4771abf --- /dev/null +++ b/sbhs_server/tables/migrations/0002_remove_experiment_checksum.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting field 'Experiment.checksum' + db.delete_column(u'tables_experiment', 'checksum') + + + def backwards(self, orm): + # Adding field 'Experiment.checksum' + db.add_column(u'tables_experiment', 'checksum', + self.gf('django.db.models.fields.CharField')(default='0', max_length=127), + keep_default=False) + + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/0003_add_field_Booking_booking_date.py b/sbhs_server/tables/migrations/0003_add_field_Booking_booking_date.py new file mode 100644 index 0000000..c6c4ec1 --- /dev/null +++ b/sbhs_server/tables/migrations/0003_add_field_Booking_booking_date.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Booking.booking_date' + db.add_column(u'tables_booking', 'booking_date', + self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2014, 5, 11, 0, 0)), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Booking.booking_date' + db.delete_column(u'tables_booking', 'booking_date') + + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'booking_date': ('django.db.models.fields.DateTimeField', [], {}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/0004_add_field_Experiment_checksum.py b/sbhs_server/tables/migrations/0004_add_field_Experiment_checksum.py new file mode 100644 index 0000000..7f17e89 --- /dev/null +++ b/sbhs_server/tables/migrations/0004_add_field_Experiment_checksum.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Experiment.checksum' + db.add_column(u'tables_experiment', 'checksum', + self.gf('django.db.models.fields.CharField')(default='NONE', max_length=255), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Experiment.checksum' + db.delete_column(u'tables_experiment', 'checksum') + + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'booking_date': ('django.db.models.fields.DateTimeField', [], {}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'checksum': ('django.db.models.fields.CharField', [], {'default': "'NONE'", 'max_length': '255'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/0005_load_boards_data.py b/sbhs_server/tables/migrations/0005_load_boards_data.py new file mode 100644 index 0000000..8ce61a7 --- /dev/null +++ b/sbhs_server/tables/migrations/0005_load_boards_data.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models +from sbhs_server.tables.models import Board + +class Migration(SchemaMigration): + + def forwards(self, orm): + for i in xrange(1, 41): + Board.objects.create(id=i, mid=i) + + def backwards(self, orm): + Board.objects.filter(mid__in=range(1,41)).delete() + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'booking_date': ('django.db.models.fields.DateTimeField', [], {}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'checksum': ('django.db.models.fields.CharField', [], {'default': "'NONE'", 'max_length': '255'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/0006_load_sample_users_data.py b/sbhs_server/tables/migrations/0006_load_sample_users_data.py new file mode 100644 index 0000000..5f287ac --- /dev/null +++ b/sbhs_server/tables/migrations/0006_load_sample_users_data.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models +from sbhs_server.tables.models import Account + +class Migration(SchemaMigration): + + def forwards(self, orm): + for i in xrange(1, 41): + account = Account( + name="Sample User %d" % i, + username="suser%d" % i, + email="suser%d@os-hardware.in" % i, + board_id=i, + is_active=1 + ) + account.set_password("suser%d%d" % (i, 4229)) + account.save() + + def backwards(self, orm): + for i in xrange(1, 41): + Account.objects.filter(username="suser%d" % i).delete() + + models = { + u'tables.account': { + 'Meta': {'object_name': 'Account'}, + 'board': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Board']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '127'}) + }, + u'tables.board': { + 'Meta': {'object_name': 'Board'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.booking': { + 'Meta': {'object_name': 'Booking'}, + 'account': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Account']"}), + 'booking_date': ('django.db.models.fields.DateTimeField', [], {}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Slot']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.experiment': { + 'Meta': {'object_name': 'Experiment'}, + 'booking': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['tables.Booking']"}), + 'checksum': ('django.db.models.fields.CharField', [], {'default': "'NONE'", 'max_length': '255'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'tables.slot': { + 'Meta': {'object_name': 'Slot'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'end_hour': ('django.db.models.fields.IntegerField', [], {}), + 'end_minute': ('django.db.models.fields.IntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_hour': ('django.db.models.fields.IntegerField', [], {}), + 'start_minute': ('django.db.models.fields.IntegerField', [], {}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['tables']
\ No newline at end of file diff --git a/sbhs_server/tables/migrations/__init__.py b/sbhs_server/tables/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/tables/migrations/__init__.py diff --git a/sbhs_server/tables/models.py b/sbhs_server/tables/models.py new file mode 100644 index 0000000..7c18298 --- /dev/null +++ b/sbhs_server/tables/models.py @@ -0,0 +1,228 @@ +from django.db import models +from django.contrib.auth.models import AbstractBaseUser +from undelete.models import TrashableMixin +import random, datetime, os +from sbhs_server.helpers import mailer, simple_encrypt +from django.contrib.auth.models import UserManager +from sbhs_server import settings +from yaksh.models import Profile +# Create your models here. + +class Board(TrashableMixin): + + mid = models.IntegerField(unique=True) + online = models.BooleanField(default=True) + + created_at = models.DateTimeField(auto_now_add=True, editable=False) + updated_at = models.DateTimeField(auto_now=True, editable=False) + + @staticmethod + def can_do_random_allotment(): + return not os.path.exists(os.path.join(settings.BASE_DIR, "WORKSHOP_MODE")) + + @staticmethod + def toggle_random_allotment(): + if Board.can_do_random_allotment(): + f = open(os.path.join(settings.BASE_DIR, "WORKSHOP_MODE"), "w") + f.close() + else: + os.remove(os.path.join(settings.BASE_DIR, "WORKSHOP_MODE")) + + @staticmethod + def allot_board(): + if Board.can_do_random_allotment(): + online_boards_count = len(settings.online_mids) + board_num = random.randrange(online_boards_count) + return settings.online_mids[board_num] + else: + last_MID = Account.objects.select_related().order_by("-id")[0].board.mid; + online_boards = sorted(settings.online_mids) + for o in online_boards: + if o > last_MID: + return o + return online_boards[0] + + def image_link(self): + return settings.WEBCAM_STATIC_DIR + "image" + str(self.mid) + ".jpeg" + + +class Account(TrashableMixin, AbstractBaseUser): + + name = models.CharField(max_length=255) + username = models.CharField(max_length=127, unique=True) + email = models.EmailField(max_length=255, unique=True) + # password = models.CharField(max_length=255) # Already covered in AbstractBaseUser + + is_active = models.BooleanField(default=False) + is_admin = models.BooleanField(default=False) + board = models.ForeignKey("Board") + + created_at = models.DateTimeField(auto_now_add=True, editable=False) + updated_at = models.DateTimeField(auto_now=True, editable=False) + + objects = UserManager() + + USERNAME_FIELD = "username" + + def get_full_name(self): + return self.name + + def get_short_name(self): + return self.name + + def send_confirmation(self): + message = """Hi,\n\nPlease visit the link """ + settings.BASE_URL + """account/confirm/""" + message = message + self.confirmation_token() + message = message + """ to confirm your account.\n\n\nRegards,\nVlabs Team""" + mailer.email(self.email, "Please confirm your account", message) + + def send_password_link(self, token): + message = """Hi,\n\nPlease visit the link """ + settings.BASE_URL + """password/edit/""" + message = message + token + message = message + """ to change your password.\n\n\nRegards,\nVlabs Team""" + mailer.email(self.email, "SBHS vlabs password reset link", message) + + def get_profile(self): + return self.profile + + + def confirmation_token(self): + return simple_encrypt.encrypt(self.email) + + +class Slot(TrashableMixin): + + start_hour = models.IntegerField() + start_minute = models.IntegerField() + + end_hour = models.IntegerField() + end_minute = models.IntegerField() + + created_at = models.DateTimeField(auto_now_add=True, editable=False) + updated_at = models.DateTimeField(auto_now=True, editable=False) + + def __str__(self): + sh = str(self.start_hour) if len(str(self.start_hour)) == 2 else "0" + str(self.start_hour) + sm = str(self.start_minute) if len(str(self.start_minute)) == 2 else "0" + str(self.start_minute) + eh = str(self.end_hour) if len(str(self.end_hour)) == 2 else "0" + str(self.end_hour) + em = str(self.end_minute) if len(str(self.end_minute)) == 2 else "0" + str(self.end_minute) + return sh + ":" + sm + " -- " + eh + ":" + em + + @staticmethod + def indices(self, other): + # These lines are irrelevant due to booking date scheme + # + # now = datetime.datetime.now() + # cur_hour = now.hour + + # s = abs(cur_hour - self.start_hour) + # s = s + 100 if self.start_hour < cur_hour else s + # o = abs(cur_hour - other.start_hour) + # o = o + 100 if other.start_hour < cur_hour else o + return self.start_hour, other.start_hour + + def __lt__(self, other): + s, o = Slot.indices(self, other) + return s < o + + def __gt__(self, other): + s, o = Slot.indices(self, other) + return s > o + + def __ne__(self, other): + s, o = Slot.indices(self, other) + return s != o + + def __eq__(self, other): + s, o = Slot.indices(self, other) + return s == o + + def __le__(self, other): + s, o = Slot.indices(self, other) + return s <= o + + def __ge__(self, other): + s, o = Slot.indices(self, other) + return s >= o + + @staticmethod + def current_slots(mid): + now = datetime.datetime.now() + slots = list(Slot.objects.filter(start_hour=now.hour, end_minute__gt=now.minute)) + bookings = Booking.objects.filter(booking_date__year=now.year, + booking_date__month=now.month, + booking_date__day=now.day, slot__in=slots, + account__board__mid=mid) + for b in bookings: + if b.slot in slots: + slots.remove(b.slot) + + return slots + + @staticmethod + def slots_now(): + now = datetime.datetime.now() + slots = list(Slot.objects.filter(start_hour=now.hour)) + return slots + + @staticmethod + def get_free_slots(mid): + now = datetime.datetime.now() + slots = list(Slot.objects.filter(start_hour__gte=now.hour)) + bookings = Booking.objects.filter(booking_date__year=now.year, + booking_date__month=now.month, + booking_date__day=now.day, slot__in=slots, + account__board__mid=mid) + for b in bookings: + if b.slot in slots: + slots.remove(b.slot) + + return sorted(slots) + + @staticmethod + def get_free_slots_on(date, mid): + now = datetime.datetime.now() + if date.strftime("%Y-%m-%d") == now.strftime("%Y-%m-%d"): + slots = list(Slot.get_free_slots(mid)) + elif date > now: + slots = list(Slot.objects.all()) + bookings = Booking.objects.filter(booking_date__year=date.year, + booking_date__month=date.month, + booking_date__day=date.day, + account__board__mid=mid) + + for b in bookings: + if b.slot in slots: + slots.remove(b.slot) + else: + slots = [] + + return sorted(slots) + + +class Booking(TrashableMixin): + + account = models.ForeignKey("Account") + slot = models.ForeignKey("Slot") + + booking_date = models.DateTimeField() + + created_at = models.DateTimeField(auto_now_add=True, editable=False) + updated_at = models.DateTimeField(auto_now=True, editable=False) + + def start_time(self): + return self.booking_date.replace(hour=self.slot.start_hour, minute=self.slot.start_minute) + + def end_time(self): + return self.booking_date.replace(hour=self.slot.end_hour, minute=self.slot.end_minute) + + +class Experiment(TrashableMixin): + + booking = models.ForeignKey("Booking") + + log = models.CharField(max_length=255) + checksum = models.CharField(max_length=255, default="NONE") + + created_at = models.DateTimeField(auto_now_add=True, editable=False) + updated_at = models.DateTimeField(auto_now=True, editable=False) diff --git a/sbhs_server/tables/models.pyc b/sbhs_server/tables/models.pyc Binary files differnew file mode 100644 index 0000000..7370f9a --- /dev/null +++ b/sbhs_server/tables/models.pyc diff --git a/sbhs_server/tables/tests.py b/sbhs_server/tables/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/tables/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/tables/views.py b/sbhs_server/tables/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/sbhs_server/tables/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/sbhs_server/thirumalesh@10.102.6.123 b/sbhs_server/thirumalesh@10.102.6.123 new file mode 100644 index 0000000..0e3d8cb --- /dev/null +++ b/sbhs_server/thirumalesh@10.102.6.123 @@ -0,0 +1,201 @@ +import serial +import os +from time import localtime, strftime, sleep + +MAP_FILE = 'map_machine_ids.txt' +LOG_FILE = '../log/sbhserr.log' + +OUTGOING_MACHINE_ID = 252 +INCOMING_FAN = 253 +INCOMING_HEAT = 254 +OUTGOING_TEMP = 255 + +MAX_HEAT = 100 +MAX_FAN = 100 + +class Sbhs: + """ This is the Single Board Heater System class """ + + def __init__(self): + # status of the board + # 0 = not connected + # 1 = connected + self.machine_id = 26 + self.device_num = 26 + self.boardcon = False + self.status = 0 + + def connect(self, machine_id): + """ Open a serial connection via USB to the SBHS using the machine id """ + # check for valid machine id number + try: + self.machine_id = int(machine_id) + except: + #with open('error.txt', 'w') as errrr: + # errrr.write('Invalid machine id specified % d' % self.machine_id) + return False + + # get the usb device file from the machine map file + try: + map_file = open(MAP_FILE, 'r') + usb_device_file = False + for mapping_str in map_file.readlines(): + mapping = mapping_str.split('=') + # if mapping for the machine id found set the usb device file and break out of loop + if mapping[0] == str(self.machine_id): + usb_device_file = mapping[1].strip() + break + # reached end of file and check if machine id entry is present in the machine map file + map_file.close() + if not usb_device_file: + print 'Error: cannot locate the USB device in the map table for machine id %d' % self.machine_id + self.log('cannot locate the USB device in the map table for machine id %d' % self.machine_id, 'ERROR') + return False + except: + # map_file.close() + print 'Error: cannot get the USB device path for the machine id %d' % self.machine_id + self.log('cannot get the USB device path for the machine id %d' % self.machine_id, 'ERROR') + return False + + # check if SBHS device is connected + if not os.path.exists(usb_device_file): + print 'SBHS device file ' + usb_device_file + ' does not exists' + self.log('SBHS device file ' + usb_device_file + ' does not exists', 'ERROR') + return False + try: + self.boardcon = serial.Serial(port=usb_device_file, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=2) #orignal stopbits = 1 + self.status = 1 + return True + except: + print 'Error: cannot connect to machine id %d' % self.machine_id + self.log('cannot connect to machine id %d' % self.machine_id, 'ERROR') + self.machine_id = -1 + self.device_num = -1 + self.boardcon = False + self.status = 0 + return False + + def connect_device(self, device_num): + """ Open a serial connection via USB to the SBHS using USB Device Number""" + # check for valid device number + try: + self.device_num = int(device_num) + except: + print 'Invalid device number specified' + return False + + usb_device_file = '/dev/ttyUSB%d' % self.device_num + # check if SBHS device is connected + if not os.path.exists(usb_device_file): + print 'SBHS device file ' + usb_device_file + ' does not exists' + self.log('SBHS device file ' + usb_device_file + ' does not exists', 'ERROR') + return False + try: + self.boardcon = serial.Serial(port=usb_device_file, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=2) # org stopbits = 1 + self.machine_id = self.getMachineId() + return True + except: + print 'Error: cannot connect to device %s' % usb_device_file + self.log('cannot connect to device %s' % usb_device_file, 'ERROR') + return False + + def setHeat(self, val): + """ Set the heat """ + if val > MAX_HEAT or val < 0: + print 'Error: heat value cannot be more than %d' % MAX_HEAT + return False + + try: + self._write(chr(INCOMING_HEAT)) + self._write(chr(val)) + return True + except: + print 'Error: cannot set heat for machine id %d' % self.machine_id + self.log('cannot set heat for machine id %d' % self.machine_id, 'ERROR') + return False + + def setFan(self, val): + """ Set the fan """ + if val > MAX_FAN or val < 0: + print 'Error: fan value cannot be more than %d' % MAX_FAN + return False + try: + self._write(chr(INCOMING_FAN)) + self._write(chr(val)) + return True + except: + print 'Error: cannot set fan for machine id %d' % self.machine_id + self.log('cannot set fan for machine id %d' % self.machine_id, 'ERROR') + return False + + def getTemp(self): + """ Get the temperature """ + try: + self.boardcon.flushInput() + self._write(chr(OUTGOING_TEMP)) + temp = ord(self._read(1)) + (0.1 * ord(self._read(1))) + return temp + except: + print 'Error: cannot read temperature from machine id %d' % self.machine_id + self.log('cannot read temperature from machine id %d' % self.machine_id, 'ERROR') + return 0.0 + + def getMachineId(self): + """ Get machine id from the device """ + try: + self.boardcon.flushInput() + self._write(chr(OUTGOING_MACHINE_ID)) + sleep(0.5) # sleep before reading machine id + machine_id = ord(self._read(1)) + return machine_id + except: + print 'Error: cannot read machine id from %s' % self.boardcon.port + self.log('cannot read machine id from %s' % self.boardcon.port, 'ERROR') + return -1 + + def disconnect(self): + """ Reset the board fan and heat values and close the USB connection """ + try: + self.boardcon.close() + self.boardcon = False + self.status = 0 + return True + except: + print 'Error: cannot close connection to the machine' + self.log('cannot close connection to the machine', 'ERROR') + return False + + def reset_board(self): + self.setFan(100) + self.setHeat(0) + + def _read(self, size): + try: + data = self.boardcon.read(size) + return data + except: + print 'Error: cannot read from machine id %d' % self.machine_id + self.log('cannot read from machine id %d' % self.machine_id, 'ERROR') + raise Exception + + def _write(self, data): + try: + self.boardcon.write(data) + return True + except: + print 'Error: cannot write to machine id %d' % self.machine_id + self.log('cannot write to machine id %d' % self.machine_id, 'ERROR') + raise Exception + + def log(self, msg, level): + try: + errfile = open(LOG_FILE, 'a') # open error log file in append mode + if not errfile: + return + log_msg = '%s %s %s\n' %(level, strftime('%d:%m:%Y %H:%M:%S', localtime()), msg) + errfile.write(log_msg) + errfile.close() + return + except: + return + diff --git a/sbhs_server/urls.py b/sbhs_server/urls.py new file mode 100644 index 0000000..32a0efc --- /dev/null +++ b/sbhs_server/urls.py @@ -0,0 +1,67 @@ +from django.conf.urls import patterns, include, url + +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + # Examples: + # url(r'^$', 'sbhs_server.views.home', name='home'), + # url(r'^blog/', include('blog.urls')), + + #url(r'^admin/', include(admin.site.urls)), + url(r'^/?$', 'sbhs_server.pages.views.index'), + url(r'^exam/', include('yaksh.urls')), + url(r'^about/?$', 'sbhs_server.pages.views.about'), + url(r'^contact/?$', 'sbhs_server.pages.views.contact'), + url(r'^info/?$', 'sbhs_server.pages.views.info'), + url(r'^downloads/?$', 'sbhs_server.pages.views.downloads'), + url(r'^theory/?$', 'sbhs_server.pages.views.theory'), + url(r'^procedure/?$', 'sbhs_server.pages.views.procedure'), + url(r'^experiments/?$', 'sbhs_server.pages.views.experiments'), + url(r'^feedback/?$', 'sbhs_server.pages.views.feedback'), + url(r'^quiz/?$', 'sbhs_server.pages.views.quiz'), + + url(r'^enter/?$', 'sbhs_server.account.views.index'), + url(r'^account/create/?$', 'sbhs_server.account.views.create'), + url(r'^account/confirm/(.*)/?$', 'sbhs_server.account.views.confirm'), + url(r'^login/?$', 'sbhs_server.account.views.login'), + url(r'^logout/?$', 'sbhs_server.account.views.logout'), + url(r'^home/?$', 'sbhs_server.account.views.home'), + + url(r'^password/?$', 'sbhs_server.password.views.new'), + url(r'^password/link/?$', 'sbhs_server.password.views.email'), + url(r'^password/edit/(.*)/?$', 'sbhs_server.password.views.edit'), + url(r'^password/update/(.*)/?$', 'sbhs_server.password.views.update'), + + url(r'^slot/?$', 'sbhs_server.slot.views.index'), + url(r'^slot/new/?$', 'sbhs_server.slot.views.new'), + url(r'^slot/show/(.*)/?$', 'sbhs_server.slot.views.show'), + url(r'^slot/create/?$', 'sbhs_server.slot.views.create'), + url(r'^slot/delete/([0-9]+)/?$', 'sbhs_server.slot.views.delete'), + + # Following to are for backward incompatibility + url(r'^hardware/checkconnection/?$', 'sbhs_server.experiment.views.check_connection'), + url(r'^hardware/clientversion/?$', 'sbhs_server.experiment.views.client_version'), + + url(r'^experiment/check_connection/?$', 'sbhs_server.experiment.views.check_connection'), + url(r'^experiment/client_version/?$', 'sbhs_server.experiment.views.client_version'), + url(r'^experiment/initiate/?$', 'sbhs_server.experiment.views.initiation'), + url(r'^experiment/experiment/?$', 'sbhs_server.experiment.views.experiment'), + url(r'^experiment/reset/?$', 'sbhs_server.experiment.views.reset'), + url(r'^experiment/logs/?$', 'sbhs_server.experiment.views.logs'), + url(r'^experiment/logs/([0-9]+)/(.+)?$', 'sbhs_server.experiment.views.download_log'), + + url(r'^show_video/?$', 'sbhs_server.webcam.views.show_video'), + url(r'^reload_image/(.*)/?$', 'sbhs_server.webcam.views.reload'), + + url(r'^admin/?$', 'sbhs_server.admin.views.index'), + url(r'^admin/bookings/?$', 'sbhs_server.admin.views.booking_index'), + url(r'^admin/webcam/?$', 'sbhs_server.admin.views.webcam_index'), + url(r'^admin/profile/([0-9]+)/?$', 'sbhs_server.admin.views.profile'), + url(r'^admin/webcam/([0-9]+)/?$', 'sbhs_server.webcam.views.show_video_to_admin'), + url(r'^admin/toggle_allotment_mode/?$', 'sbhs_server.admin.views.toggle_allotment_mode'), + url(r'^admin/validate_log_file/?$', 'sbhs_server.experiment.views.validate_log_file'), +) + +handler404 = 'sbhs_server.pages.views.e404' +handler500 = 'sbhs_server.pages.views.e500' diff --git a/sbhs_server/webcam/__init__.py b/sbhs_server/webcam/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/webcam/__init__.py diff --git a/sbhs_server/webcam/__init__.pyc b/sbhs_server/webcam/__init__.pyc Binary files differnew file mode 100644 index 0000000..b3d3fc2 --- /dev/null +++ b/sbhs_server/webcam/__init__.pyc diff --git a/sbhs_server/webcam/admin.py b/sbhs_server/webcam/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/sbhs_server/webcam/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sbhs_server/webcam/management/__init__.py b/sbhs_server/webcam/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/webcam/management/__init__.py diff --git a/sbhs_server/webcam/management/__init__.pyc b/sbhs_server/webcam/management/__init__.pyc Binary files differnew file mode 100644 index 0000000..be6dca2 --- /dev/null +++ b/sbhs_server/webcam/management/__init__.pyc diff --git a/sbhs_server/webcam/management/commands/__init__.py b/sbhs_server/webcam/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sbhs_server/webcam/management/commands/__init__.py diff --git a/sbhs_server/webcam/management/commands/reload_images.py b/sbhs_server/webcam/management/commands/reload_images.py new file mode 100644 index 0000000..5b735cb --- /dev/null +++ b/sbhs_server/webcam/management/commands/reload_images.py @@ -0,0 +1,12 @@ +from django.core.management.base import BaseCommand +from sbhs_server.tables.models import Board +from sbhs_server.webcam.views import load_image + +class Command(BaseCommand): + args = '' + help = 'Reloads images for all SBHS machines' + + def handle(self, *args, **options): + boards = Board.objects.all() + for b in boards: + load_image(b.mid) diff --git a/sbhs_server/webcam/models.py b/sbhs_server/webcam/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sbhs_server/webcam/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sbhs_server/webcam/models.pyc b/sbhs_server/webcam/models.pyc Binary files differnew file mode 100644 index 0000000..9026348 --- /dev/null +++ b/sbhs_server/webcam/models.pyc diff --git a/sbhs_server/webcam/tests.py b/sbhs_server/webcam/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sbhs_server/webcam/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sbhs_server/webcam/views.py b/sbhs_server/webcam/views.py new file mode 100644 index 0000000..d765730 --- /dev/null +++ b/sbhs_server/webcam/views.py @@ -0,0 +1,47 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +import os, requests +from sbhs_server import settings +from django.http import HttpResponse +from sbhs_server.admin.views import checkadmin +from sbhs_server.tables.models import Board +# Create your views here. +# + +def load_image(mid): +# for images on server 15, it will gstream the photos on reload + if int(mid) in range(8,17): + command = "streamer -q -f jpeg -c /dev/video" + str(mid) + command += " -o " + settings.WEBCAM_DIR + "/image" + str(mid) + ".jpeg" + os.system(command) + + else: + take_snapshot = requests.get("http://10.102.152.16:8080/webcams/%d/take_snapshot" % int(mid)) + get_image_link = "http://10.102.152.16:8080/webcams/%d/get_image_data" % int(mid) + + command = "curl -s %s > %s/image%d.jpeg" % (get_image_link, str(settings.WEBCAM_DIR), int(mid)) + os.system(command) +def reload(req, mid): + + load_image(mid) + return HttpResponse("") + +@login_required(redirect_field_name=None) +def show_video(req): + board = req.user.board + + image_link = board.image_link() + mid = str(board.mid) + +# image_link = board.image_link() + + return render(req, "webcam/show_video.html", {"image_link": image_link, "mid": mid}) + + +@login_required(redirect_field_name=None) +def show_video_to_admin(req, mid): + checkadmin(req) + board = Board.objects.get(mid=int(mid)) + image_link = board.image_link() + mid = str(board.mid) + return render(req, "webcam/show_video.html", {"image_link": image_link, "mid": mid}) diff --git a/sbhs_server/webcam/views.py-bkup b/sbhs_server/webcam/views.py-bkup new file mode 100644 index 0000000..d765730 --- /dev/null +++ b/sbhs_server/webcam/views.py-bkup @@ -0,0 +1,47 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +import os, requests +from sbhs_server import settings +from django.http import HttpResponse +from sbhs_server.admin.views import checkadmin +from sbhs_server.tables.models import Board +# Create your views here. +# + +def load_image(mid): +# for images on server 15, it will gstream the photos on reload + if int(mid) in range(8,17): + command = "streamer -q -f jpeg -c /dev/video" + str(mid) + command += " -o " + settings.WEBCAM_DIR + "/image" + str(mid) + ".jpeg" + os.system(command) + + else: + take_snapshot = requests.get("http://10.102.152.16:8080/webcams/%d/take_snapshot" % int(mid)) + get_image_link = "http://10.102.152.16:8080/webcams/%d/get_image_data" % int(mid) + + command = "curl -s %s > %s/image%d.jpeg" % (get_image_link, str(settings.WEBCAM_DIR), int(mid)) + os.system(command) +def reload(req, mid): + + load_image(mid) + return HttpResponse("") + +@login_required(redirect_field_name=None) +def show_video(req): + board = req.user.board + + image_link = board.image_link() + mid = str(board.mid) + +# image_link = board.image_link() + + return render(req, "webcam/show_video.html", {"image_link": image_link, "mid": mid}) + + +@login_required(redirect_field_name=None) +def show_video_to_admin(req, mid): + checkadmin(req) + board = Board.objects.get(mid=int(mid)) + image_link = board.image_link() + mid = str(board.mid) + return render(req, "webcam/show_video.html", {"image_link": image_link, "mid": mid}) diff --git a/sbhs_server/wsgi.py b/sbhs_server/wsgi.py new file mode 100644 index 0000000..dbec7e8 --- /dev/null +++ b/sbhs_server/wsgi.py @@ -0,0 +1,14 @@ +""" +WSGI config for sbhs_server project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sbhs_server.settings") + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() |