Commit 89ffc4ae authored by Darshan Prabhu's avatar Darshan Prabhu

Dashboards with all forms and models

parent 544eea6a
from functools import reduce
# Part 1 (get these from the webapp)
# get student list
# get student project priorities and let them apply to their top priority
S = {"s1":["p1", "p3", "p2", "p4"], "s2":["p1", "p3", "p2", "p4"]}
# S = {"s1":["p1", "p2", "p3", "p4"], "s2":["p1", "p4", "p3", "p2"], "s3":["p3", "p1", "p2", "p4"], "s4":["p3", "p2", "p1", "p4"]}
# get project list from profs, per project capactiy and total capacity
L = {"l1":["p1", "p2"], "l2":["p3", "p4"]}
# L = {"l1":["p1", "p2"], "l2":["p3", "p4"]}
P2L = {"p1":"l1", "p2":"l1", "p3":"l2", "p4":"l2"}
# get priorities from profs about students
Lpref = {"l1": ["s1", "s2"], "l2": ["s2", "s1"]}
# Lpref = {"l1": ["s3", "s4", "s1", "s2"], "l2": ["s1", "s2", "s3", "s4"]}
# get max intake
Pc = {"p1":1, "p2":1, "p3":1, "p4":1}
# Pc = {"p1":2, "p2":1, "p3":2, "p4":1}
# matching structure
Ms = {"s1": [], "s2": []}
# Ms = {"s1": [], "s2": [], "s3": [], "s4": []}
Mp = {"p1": [], "p2": [], "p3": [], "p4": []}
# print("MS values: ", Ms.values())
# isStable = reduce(lambda x, y: (x and (len(y)>0), Ms.values(), True)
isStable = True
for i in Ms.values():
if len(i)==0:
isStable = False
break
# print(isStable)
# Part 2 (compute and return to the webapp)
# Run algo
while not isStable:
for stud in Ms.keys():
if len(Ms[stud])==0:
# provisionally asigning
# print("Current student: ", stud)
proj = S[stud][0]
lec = P2L[proj]
Ms[stud].append(proj)
Mp[proj].append(stud)
# check if project is oversubscibed
while len(Mp[proj]) > Pc[proj]:
# find the least priority students assigned to the project
prefList = Lpref[lec] # pref order of lec
idx = len(prefList)-1
found = False
while not found:
if prefList[idx] in Mp[proj]:
Mp[proj].remove(prefList[idx])
Ms[prefList[idx]].remove(proj)
S[prefList[idx]].remove(proj)
prefList.remove(prefList[idx])
# print("Removing project: ", proj)
# print("from student: ", prefList[idx])
found = True
else:
idx -= 1
# isStable = reduce(lambda x, y: (x and (len(y)>0), Ms.values(), True)
isStable = True
for i in Ms.values():
if len(i)==0:
isStable = False
break
print(Ms)
\ No newline at end of file
......@@ -37,6 +37,9 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'guideAllocationPortal',
'multiselectfield',
'django_drf_filepond'
]
MIDDLEWARE = [
......@@ -80,6 +83,11 @@ DATABASES = {
}
}
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
......@@ -118,3 +126,5 @@ USE_TZ = True
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
DJANGO_DRF_FILEPOND_UPLOAD_TMP = os.path.join(BASE_DIR, 'guideAllocationPortal/static/resume-temp-uploads')
DJANGO_DRF_FILEPOND_FILE_STORE_PATH = os.path.join(BASE_DIR, 'guideAllocationPortal/static/resume-uploads')
\ No newline at end of file
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<title>GAP</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.7/semantic.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/components/icon.min.css" integrity="sha512-8Tb+T7SKUFQWOPIQCaLDWWe1K/SY8hvHl7brOH8Nz5z1VT8fnf8B+9neoUzmFY3OzkWMMs3OjrwZALgB1oXFBg==" crossorigin="anonymous" />
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.7/semantic.min.js"></script>
<style type="text/css">
.typewriter h1 {
color: #fff;
font-family: monospace;
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .15em solid orange; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
margin: 0 auto; /* Gives that scrolling effect as the typing happens */
letter-spacing: .1em; /* Adjust as needed */
animation:
typing 3.5s steps(30, end),
blink-caret .5s step-end infinite;
}
/* The typing effect */
@keyframes typing {
from { width: 0 }
to { width: 100% }
}
/* The typewriter cursor effect */
@keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: orange }
}
form h4 {
font-size: 1.5rem;
text-align: center;
padding-bottom: 1rem;
font-family: monospace;
}
</style>
</head>
<body>
<div class="ui two column grid" style="min-height: 100%;">
<div class="column ui aligned grid teal">
<div class="column" style="top:35%;padding-left: 13%;">
<div class=typewriter>
<h1 style="font-size: 2.5rem;">Guide Allocation Portal</h1>
</div>
<h3 style="font-size: 1.5rem;font-family: monospace;padding-left: inherit;">CSE Department, IIT Bombay</h3>
</div>
</div>
<div class="column">
<form class="ui large form" action="POST" style="top: 32%;padding-left: 2rem;">
<h4 >Login now</h4>
<div class="ui">
<div class="field" style="padding-bottom: 1rem;">
<div class="ui left icon input">
<i class="user icon"></i>
<input type="text" name="ldap" placeholder="CSE username">
</div>
</div>
<div class="field" style="padding-bottom: 1rem;">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="password" name="password" placeholder="Password">
</div>
</div>
<button class="ui fluid large black submit button" type="submit">Login</button>
</div>
</form>
</div>
</div>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
......@@ -14,8 +14,11 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
path('admin/', admin.site.urls),
path('',include(("guideAllocationPortal.urls","gap"),namespace="gap")),
url(r'^fp/', include('django_drf_filepond.urls')),
]
from django.forms.models import inlineformset_factory
from django.forms import ModelForm, TextInput, NumberInput, Select, Textarea, DateInput
from .models import PositionsModel, RequisitesModel, StudentDetailModel, StudentProjectsModel, StudentEducationModel
# Form to get the project details from faculty
class PositionsModelForm(ModelForm):
class Meta:
model = PositionsModel
exclude = ('faculty','initial_total_positions',)
widgets = {
'title': TextInput(attrs={'placeholder':'Project Title'}),
'total_positions':NumberInput(attrs={'placeholder':'Total Positions'}),
'contact_details': TextInput(attrs={'placeholder':'How to contact me?'})
}
# Form to get the requisites list from faculty
class RequisitesModelForm(ModelForm):
class Meta:
model = RequisitesModel
exclude = ()
widgets = {
'Subject':Select(attrs={'class':"ui fluid search dropdown"}),
'cgpa':NumberInput(attrs={'placeholder':'CGPA','step':0.001})
}
# Formset to attach requisites form to main project form
RequisitesFormset = inlineformset_factory(PositionsModel,RequisitesModel,form=RequisitesModelForm,
extra=1,can_delete=False)
# Form to get student Details
class StudentDetailModelForm(ModelForm):
class Meta:
model = StudentDetailModel
exclude = ('student',)
# Form to get student project Details
class StudentProjectsModelForm(ModelForm):
class Meta:
model = StudentProjectsModel
exclude = ()
widgets = {
'title':TextInput(attrs={'placeholder':'Project Title'}),
'description': Textarea(attrs={'rows': 3}),
'link':TextInput(attrs={'placeholder':'Github Link'})
}
# Form to get student education Details
class StudentEducationModelForm(ModelForm):
class Meta:
model = StudentEducationModel
exclude = ()
widgets = {
'year': DateInput(attrs={'placeholder':'yyyy-mm-dd'}),
'exam': Select(attrs={'class':'ui selection dropdown'})
}
# Formset to attach projects form to main student detail form
StudentProjectFormset = inlineformset_factory(StudentDetailModel,StudentProjectsModel,form=StudentProjectsModelForm,
extra=1,can_delete=False)
# Formset to attach education form to main student detail form
StudentEducationFormset = inlineformset_factory(StudentDetailModel,StudentEducationModel,form=StudentEducationModelForm,
extra=1,can_delete=False)
from django.db import models
from django_drf_filepond.models import StoredUpload
from django.core.validators import MinValueValidator, MaxValueValidator
from django.contrib.auth.models import User
from django.conf import settings
# Create your models here.
from .choices import *
from multiselectfield import MultiSelectField
from datetime import datetime,timedelta
import os
# Model to store the project details
class PositionsModel(models.Model):
faculty = models.ForeignKey(User, on_delete=models.DO_NOTHING, null=False,
blank=False,default=None, related_name='position_user')
title = models.CharField(verbose_name="Project Title",max_length=100,blank=False,null=False)
description = models.TextField(blank=True,null=True,verbose_name="Description")
contact_details = models.CharField(verbose_name="Contact Details",max_length=200,null=True,blank=True)
total_positions = models.IntegerField(verbose_name="Total Positions",null=False,blank=False)
initial_total_positions = models.IntegerField(verbose_name="Initial Total Positions",null=True,blank=True)
def get_requisites(self):
# Gives the list of all requisites for particular project
return self.requisites.all()
def get_alloted_students(self):
# Gives list of all students alloted to this project
return self.student_mappings.all()
# Model to store requisites for every project
class RequisitesModel(models.Model):
position = models.ForeignKey(PositionsModel,related_name='requisites',on_delete=models.CASCADE)
Subject = models.CharField(verbose_name="Subject Name",max_length=6,choices=subject_choices,default='CS699')
cgpa = models.FloatField(verbose_name="CGPA",null=False,blank=False,
validators=[MinValueValidator(0.0),MaxValueValidator(10.0)])
# Model to store details of student profile
class StudentDetailModel(models.Model):
student = models.ForeignKey(User, on_delete=models.DO_NOTHING, null=False,
blank=False,default=None, related_name='student_user')
qualities = models.CharField(verbose_name="Description",max_length=200,blank=True,null=True)
alloted_project = models.ForeignKey(PositionsModel,on_delete=models.DO_NOTHING,blank=True,default=None,null=True,related_name="alloted_student")
def get_education_details(self):
# Gives the list of all education details for student
return self.education.all()
def get_project_details(self):
# Gives the list of all project details for student
return self.projects.all()
def get_resume_details(self):
# Gives the resume associated with the student
return self.resume.first()
def get_cgpa(self):
# Gives the BE/Btech cgpa of the student the student
if self.education.exists():
return self.education.get(exam='BE/BTech').cgpa
else:
return 0
def get_alloted_project(self):
if self.student_allotment:
return self.student_allotment.project.title
else:
return None
# Model to store details of student projects
class StudentProjectsModel(models.Model):
student = models.ForeignKey(StudentDetailModel,related_name='projects',on_delete=models.CASCADE)
title = models.CharField(verbose_name="Project Title",max_length=100,blank=False,null=False)
languages = MultiSelectField(verbose_name="Programming Languages",choices=language_choices)
description = models.TextField(verbose_name="Description",blank=True,null=True)
link = models.URLField(verbose_name="Github Link",max_length=200,blank=True,null=True)
# Model to store details of student education
class StudentEducationModel(models.Model):
student = models.ForeignKey(StudentDetailModel,related_name='education',on_delete=models.CASCADE)
exam = models.CharField(verbose_name="Examination",max_length=10,choices=exam_choices,default="BE/BTech")
board = models.CharField(verbose_name="Examination Board",max_length=100,blank=False,null=False)
cgpa = models.FloatField(verbose_name="CGPA/Percentage",null=False,blank=False,
validators=[MinValueValidator(0.0),MaxValueValidator(100.0)])
year = models.DateField(verbose_name="Year of completion",null=False,blank=False)
# Model to store details of student resume
class StudentResumeModel(models.Model):
student = models.ForeignKey(StudentDetailModel,related_name="resume",on_delete=models.CASCADE)
file = models.ForeignKey(StoredUpload,on_delete=models.DO_NOTHING)
# Model to store generated mappings for every round
class GeneratedMappingsModel(models.Model):
roundNo = models.IntegerField(verbose_name="Round Number",null=False,blank=False,default=1)
project = models.ForeignKey(PositionsModel,related_name="student_mappings",on_delete=models.DO_NOTHING,db_column="project_id")
faculty = models.ForeignKey(User,on_delete=models.DO_NOTHING,db_column="faculty_id")
student = models.ForeignKey(StudentDetailModel,related_name="student_allotment",on_delete=models.DO_NOTHING,db_column="student_id")
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}GAP{% endblock %}</title>
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
<link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet">
<!-- add before </body> -->
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.7/semantic.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/dataTables.semanticui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.7/semantic.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/components/icon.min.css" integrity="sha512-8Tb+T7SKUFQWOPIQCaLDWWe1K/SY8hvHl7brOH8Nz5z1VT8fnf8B+9neoUzmFY3OzkWMMs3OjrwZALgB1oXFBg==" crossorigin="anonymous" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/dataTables.semanticui.min.css" />
<style type="text/css">
body{
background-color: whitesmoke;
}
#navbar{
font-size:medium;
padding-top: 1vh;
padding-bottom:1vh;
}
#navbar .header{
font-size: x-large;
font-family: monospace;
color:#00b5ad;
}
{% block styling %}
{% endblock styling %}
</style>
</head>
<body>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=BioRhyme:wght@300&display=swap" rel="stylesheet">
<div id="navbar" class="ui inverted segment tiny" style="margin-top: 0;padding: 4px; ">
<div class="ui inverted secondary stackable menu">
<div class="header item ">
<p class="teal" style="font-family: 'BioRhyme', serif;letter-spacing: 4px;">Guide Allocation Portal</p>
</div>
<div class="right menu">
<p class="item" style="font-size: large;">
Welcome {{ request.user.get_full_name }}
</p>
<div class="item">
<form action="{% url 'gap:logout' %}">
<button class="ui button teal" type='submit'>Log out</button>
</form>
</div>
</div>
</div>
</div>
<div class="ui container" style="width: 75%;">
{% block content %}
{% endblock %}
</div>
<div class="modals">
{% block modals %}
{% endblock %}
</div>
<script type="text/javascript">
{% block scripts %}
{% endblock %}
</script>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
from django.urls import path, include
from .views import LoginView, LogoutView, dashboardView, shortlistView, updatePriorityView, generateMappingsView
urlpatterns = [
path('',dashboardView.as_view(),name="dashboard"),
path('generatemapping',generateMappingsView,name="generateMapping")
]
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment