Commit 6feb884f authored by KUNAL GOYAL's avatar KUNAL GOYAL

changes

parents c92e8e88 951d249b
......@@ -22,24 +22,31 @@ General Allocation Portal
1. In terminal, cd to the project directory `cd project`
2. Then run the command `python3 manage.py makemigrations` and then `python3 manage.py migrate`. These commands start a new database or modify the existing database.
3. To start the local host and run the portal, run the command `python3 manage.py runserver`. You should get an output as:
>Performing system checks...
>Performing system checks...
>System check identified no issues (0 silenced).
>October 31, 2014 - 16:23:39
>Django version 1.7.1, using settings 'mysite.settings'
>Starting development server at http://127.0.0.1:8000/
>Quit the server with CONTROL-C.
4. Now start the localhost server in your web browser by going to the link http://127.0.0.1:8000/
4. Now open the GAP website in your web browser by going to the link http://127.0.0.1:8000/
5. To create an admin use the command `python3 manage.py createsuperuser` in the terminal.
6. You can use the various links to register, login and manage accounts using the links provided on the home page or also do the same using the admin page which can accessed using the URL http://127.0.0.1:8000/admin/
7. Once your institute has registered, your rank etc provided by the institute are stored in the server sqlite database along with the choices, including those allocated to you and those preferred by you, from those made available by the institute. These choices are displayed once you log in.
6. Click on the 'Register with us' link on the homepage to register an institute and create its portal.
7. Once your institute has registered click on the link 'Institute login' to login to your dashboard.
8. You will find links for applicants and choices and on clicking them, all the corresponding existing database will be displayed.
9. Initially there will be no choices available. To add applicats and choices, click on the upload file button to and select a csv file with the appropriate format.
10. The csv file format of the choices is: choice name, choice capacity
11. The csv file format of the applicants is: name, rank, email-id, account-password
12. After uploading the file for applicants, corresponding users with the username as 'name' and password as 'user_password' will be created.
13. The applicants can login by clicking the link 'Applicant login'. After login students can fill their rspective choices and priorities and submit.
14. The institute can then allocate the applicants by clicking 'Allocate' button on teir dashboard.
15. The applicants will now be have the options to freeze, float or drop their choices.
Task-wise details:
--------------------------------------------------------------------------------------------------------------------------------------------------------
1. **Allocation:**
* It is relatively simple to implement.
* Sort the students in order of their rank and allocated as per the rank list.
* Checking it's correctness is tough. One needs to solve the test cases manually and then check with the program output.
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 14:07
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Allocationcl',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'verbose_name_plural': 'Allocated Choice',
'ordering': ['applicant__rank'],
'verbose_name': 'Allocated Choice',
},
),
migrations.CreateModel(
name='Applicant',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('rank', models.IntegerField(validators=[django.core.validators.MinValueValidator(1)])),
],
),
migrations.CreateModel(
name='Application',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('priority', models.IntegerField(validators=[django.core.validators.MinValueValidator(1)])),
('applicant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='allocation.Applicant')),
],
options={
'ordering': ['priority'],
},
),
migrations.CreateModel(
name='Choice',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('choice_name', models.CharField(max_length=200)),
('capacity', models.IntegerField()),
('seats_left', models.IntegerField(default=0)),
],
),
migrations.CreateModel(
name='Institute',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
],
options={
'verbose_name_plural': 'Institutes',
'verbose_name': 'Institute',
},
),
migrations.AddField(
model_name='choice',
name='institute',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='allocation.Institute'),
),
migrations.AddField(
model_name='application',
name='choice',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='allocation.Choice'),
),
migrations.AddField(
model_name='applicant',
name='alloted_choice',
field=models.ManyToManyField(related_name='alloted_applicant', through='allocation.Allocationcl', to='allocation.Choice'),
),
migrations.AddField(
model_name='applicant',
name='choices',
field=models.ManyToManyField(related_name='applicants', through='allocation.Application', to='allocation.Choice'),
),
migrations.AddField(
model_name='applicant',
name='institute',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='applicants', to='allocation.Institute'),
),
migrations.AddField(
model_name='allocationcl',
name='applicant',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='allocation.Applicant'),
),
migrations.AddField(
model_name='allocationcl',
name='choice',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='allocation.Choice'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 14:21
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('allocation', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='choice',
old_name='seats_left',
new_name='seats_filled',
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 14:37
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('allocation', '0002_auto_20171025_1951'),
]
operations = [
migrations.RemoveField(
model_name='choice',
name='seats_filled',
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 14:51
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('allocation', '0003_remove_choice_seats_filled'),
]
operations = [
migrations.AddField(
model_name='choice',
name='seats_filled',
field=models.IntegerField(default=0),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 15:38
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('allocation', '0004_choice_seats_filled'),
]
operations = [
migrations.AddField(
model_name='institute',
name='is_allocated',
field=models.BooleanField(default=True),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 15:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('allocation', '0005_institute_is_allocated'),
]
operations = [
migrations.AddField(
model_name='applicant',
name='is_float',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='institute',
name='is_allocated',
field=models.BooleanField(default=False),
),
]
......@@ -10,7 +10,7 @@
z-index: -1;
background-image: url('BG.png');
/*background-size: 2000px 700px;*/
background-size: 100% 75%;
background-size: 100% 100%;
background-repeat: no-repeat;
background-attachment: fixed;
opacity: 0.60;
......
......@@ -31,18 +31,28 @@
{% block content %}
{% if request.get_full_path == "/allocation/admin" %}
<div style="float:right; vertical-align: top;">
<div style="float:right;">
<form method="POST" action="/allocation/button_action" enctype="multipart/form-data">
{% csrf_token %}
<button type="submit" style="width: 180px; height: 40px; font-size: 25px"> Allocate</button>
</form>
</div>
{% endif %}
<ul>
<li><p style="font-size: 20px;"><a href="{% url 'allocation:applicant_list' %}">Applicants</a></p>
<li><p style="font-size: 20px;"><a href="{% url 'allocation:choice_list' %}">Choices</a></p>
</ul>
<p style="font-size: 20px; text-align: left;"><a href="{% url 'allocation:applicant_list' %}">Applicants</a></p>
<p style="font-size: 20px; text-align: left"><a href="{% url 'allocation:choice_list' %}">Choices</a></p>
<!-- {% if request.get_full_path == "/allocation/admin" %}
<div style="float:right; vertical-align: top; margin-top: -140px">
<form method="POST" action="/allocation/button_action" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="prikey" value="{{ request.get_full_path }}">
<button type="submit" style="width: 180px; height: 40px; font-size: 25px"> Allocate</button>
</form>
<div> -->
<!-- {% endif %} -->
{% endblock %}
......@@ -9,14 +9,57 @@
{% block content %}
<h1>Applicants</h1>
<!-- <script>
function validate_fileupload(fileName){
var allowed_extensions = "csv";
var file_extension = fileName.split('.').pop();
// document.getElementById('errfn').innerHTML = file_extension;
if(allowed_extensions==file_extension){
return true; // valid file extension
}
// document.getElementById('errfn').innerHTML = "This is not a valid file format";
alert("Sorry, only .txt files are allowed");
return false;
}
</script> -->
<!--
{% if success %}
<ul>
<li style="float:right; vertical-align: top;">
<h3 style="margin-top: -50px"> For uploading Applicant</h3>
<form name="myform" method="POST" action="/allocation/applicant_make" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" accept=".csv" id="upload_file" title='Please upload file in .csv format only'>
<button type="submit">Upload</button>
<div id="errfn">
<p style="color:red">Invalid input</p>
</div>
</form>
</li>
{% for applicant in applicant_list %}
<li>
<a href="{% url 'allocation:applicant-detail' applicant.pk %}">{{ applicant.name }}</a>
</li>
{% endfor %}
</ul>
{% else %} -->
{% if applicant_list %}
<ul>
<li style="float:right; vertical-align: top;">
<h3 style="margin-top: -50px"> For uploading Applicant</h3>
<form method="POST" action="/allocation/applicant_make" enctype="multipart/form-data">
<form name="myform" method="POST" action="/allocation/applicant_make" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" title='Please upload file in .csv format only'>
<input type="file" name="myfile" accept=".csv" id="upload_file" title='Please upload file in .csv format only'>
<button type="submit">Upload</button>
<div id="errfn">
{% if success %}
<p style="color:red">Invalid input</p>
{% endif %}
</div>
</form>
</li>
{% for applicant in applicant_list %}
......@@ -31,10 +74,12 @@
<h3 style="margin-top: -50px"> For uploading Applicant</h3>
<form method="POST" action="/allocation/applicant_make" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" title='Please upload file in .csv format only'>
<input type="file" name="myfile" accept=".csv" title='Please upload file in .csv format only'>
<button type="submit">Upload</button>
</form>
</li>
<p>There are no applicants.</p>
{% endif %}
<!-- {% endif %} -->
{% endblock %}
......@@ -36,7 +36,7 @@
<h3 style="margin-top: -50px"> For uploading choices</h3>
<form method="POST" action="/allocation/choice_make" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" title='Please upload file in .csv format only'>
<input type="file" accept=".csv" name="myfile" title='Please upload file in .csv format only'>
<button type="submit">Upload</button>
</form>
</li>
......
......@@ -13,8 +13,45 @@ from django.contrib.auth import authenticate, login
from django import forms
import csv
from django.urls import reverse_lazy
from django.utils import lru_cache
from django.utils._os import upath
from django.utils.encoding import force_text
from django.utils.functional import lazy
from django.utils.html import format_html
from django.utils.module_loading import import_string
from django.utils.six import string_types, text_type
from django.utils.translation import ugettext as _, ungettext
from django.contrib.auth import *
from allocation.forms import *
from alloc import *
from difflib import SequenceMatcher
from django.core.mail import send_mail
from django.core.mail import EmailMessage
from django.core.exceptions import (
FieldDoesNotExist, ImproperlyConfigured, ValidationError,
)
# @login_required(login_url='/admin/login')
# def index(request): #for /allocation
# applicant=Applicant.objects.filter(name=request.user.username)[0]
# # form = PreferenceForm(
# # initial={'name': applicant.name , 'rank': applicant.rank}
# # )
# form = ArticleForm(instance=applicant)
# return render(request, 'allocation/index.html', {'applicant': applicant, 'form': form})
# def send_mail(request):
# # send_mail('Subject here', 'Here is the message.', settings.EMAIL_HOST_USER,['to@example.com'], fail_silently=False)
# email = EmailMessage(
# 'subject_message',
# 'content_message',
# 'sender smtp gmail' +'<codemafia123@gmail.com>',
# ['codemafia123@gmail.com'],)
# email.send()
# return HttpResponse("success")
def signup(request):
if request.method == 'POST':
......@@ -30,46 +67,118 @@ def signup(request):
form = InstiForm()
return render(request, 'registration/register.html', {'form': form})
def button_action(request):
institute=request.user.username
allocator(institute)
return HttpResponse("success")
def home(request):
documents = Document.objects.all()
return render(request, 'core/home.html', { 'documents': documents })
return HttpResponse("On home")
## View for the button 'Allocate'
# @brief On clicking the button 'Allocate' user is directed to this view and its url "/allocation/button_action"
def button_action(request):
institute=request.user.username #< login institute name
allocator(institute) #< calls the function allocator in 'alloc.py'
return HttpResponseRedirect("/allocation/admin")
## View for the button 'Upload' in choice_list.html
# @brief On clicking the button 'Upload' all the .csv choices are validated and the uploaded
def choice_make(request):
if request.method == "POST":
csvfile = request.FILES['myfile']
csvfile = request.FILES['myfile'] #< Uploaded csv file
file_data = csvfile.read().decode("utf-8")
lines = file_data.split("\n")
user_name = request.user.username
institute = get_object_or_404(Institute, name=user_name)
lines = file_data.split("\n") #< split the csv file into lines
user_name = request.user.username #< logged in institute name
institute = get_object_or_404(Institute, name=user_name) #< Institute object corresponding to logged in institute
repeated = [] #< this list keeps track of repeated choices
for line in lines:
line = line.split(',')
number = len(line)
if number != 2: #< If the number of columns is not equal to two then display error
return HttpResponse("Incorrect data format in uploaded .csv file.")
existing_no = institute.choices.filter(choice_name=line[0]) #< Get existing choices(if exist) of the particular institute
if existing_no.count() != 0:
repeated.append(line[0])
if len(repeated) != 0: #< If there exists Repeating choices then display all the repeated choices
str = ""
for rep in repeated:
str += rep + ","
return HttpResponse(".csv file has choices: '"+ str + "' that already exists")
for line in lines:
line = line.split(',')
tmp = institute.choices.create(choice_name=line[0],capacity=line[1])
tmp.save()
return HttpResponse("successful")
return HttpResponse("Error")
return HttpResponseRedirect("/allocation/admin/choices")
return HttpResponse("Error") #< If not a 'POST' query then display error
## Django function for getting default password validators
@lru_cache.lru_cache(maxsize=None)
def get_default_password_validators():
return get_password_validators(settings.AUTH_PASSWORD_VALIDATORS)
def get_password_validators(validator_config):
validators = []
for validator in validator_config:
try:
klass = import_string(validator['NAME'])
except ImportError:
msg = "The module in NAME could not be imported: %s. Check your AUTH_PASSWORD_VALIDATORS setting."
raise ImproperlyConfigured(msg % validator['NAME'])
validators.append(klass(**validator.get('OPTIONS', {})))
return validators
## View for the button 'Upload' in applciant_list.html
def applicant_make(request):
if request.method == "POST":
csvfile = request.FILES['myfile']
csvfile = request.FILES['myfile'] #< Uploaded csv file
file_data = csvfile.read().decode("utf-8")
user_name = request.user.username
institute = get_object_or_404(Institute, name=user_name)
lines = file_data.split("\n")
user_name = request.user.username #< Name of the logged in institute
institute = get_object_or_404(Institute, name=user_name) #< Institute object corresponding to the logged in institute
lines = file_data.split("\n") #< splits csv file into lines
rep_users = [] #< This list keeps track of the repeated users
rep_applicant = [] #< This list keeps track of the repeated applicants
errors = [] #< This list keeps track of the users with invalid passwords
for line in lines:
line = line.split(',')
tmp = institute.applicants.create(name = line[0],rank = line[1])
number = len(line)
if number != 4: #< Checks whether the number of columns is equal to 4 or not
return HttpResponse("Incorrect data format in uploaded .csv file")
existing_no_app = institute.applicants.filter(name = line[0]) #< Query set of applicants that already exist and match with the name of the applicant in csv file
existing_no_user = User.objects.filter(username=line[0]) #< Query set of users that already exist and match with the name of the applicant in csv file
if existing_no_app.count() != 0:
rep_applicant.append(line[0])
if existing_no_user.count() != 0:
rep_users.append(line[0])
password_validators = get_default_password_validators() #< Get validators for validating the passwords
for validator in password_validators:
try:
validator.validate(line[3])
except ValidationError as error:
errors.append(line[0])
if len(rep_applicant) != 0: #< if there already exist applicants matching our .csv file
str = ""
for appl in rep_applicant:
str += appl + ","
return HttpResponse(".csv file has applicants: '"+ str + "' that already exists")
if len(rep_users) != 0: #< if there already exist users matching our .csv file
str = ""
for appl in rep_users:
str += appl + ","
return HttpResponse(".csv file has user with usernames : '"+ str + "' that already exists")
if len(errors) != 0: #< if some passwords are invalid
str = ""
for appl in errors:
str += appl + ","
return HttpResponse(".csv file usernames : '"+ str + "' have incorrect format of password")
for line in lines: #< All fields provided are valid and hence create Applicants and users
line = line.split(',')
tmp = institute.applicants.create(name = line[0],rank = line[1]) #< Creating Applicant
tmp.save()
user = User.objects.create_user(username=line[2],email=line[3],password=line[4])
user.is_staff = True
user = User.objects.create_user(username=line[0],email=line[2],password=line[3]) #< Creating user
user.is_staff = True #< Giving staff permission to the user
user.save()
return HttpResponse("successful")
return HttpResponseRedirect("/allocation/admin/applicants")
return HttpResponse("Error")
## Makes the "fill choices" for the student login
......
......@@ -2,40 +2,54 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="{% static 'allocation/home_page.css' %}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(window).scroll(function () {
if ($(window).scrollTop() > 226) {
$(".header").addClass("fixed");
} else {
$(".header").removeClass("fixed");
}
});
</script>
<style type="text/css">
.fixed {
position:fixed;
top:0;
left:0;
}
</style>
</head>
<body>
<table >
<!-- <table >
<tr>
<td rowspan="2"><a class="logoText"><img src="{% static 'allocation/logo.png' %}" width="100%" height="100%" alt="logo"></a></td>
<td style="vertical-align: bottom; padding-left:5px; padding-bottom: 2px; font-size: 20px"><a class="logoText" ><B>codeMAFIA</B></a></td>
</tr>
<tr>
<td style="vertical-align: top; padding-left:20px; font-size:20px"><a class="tagLine" ><B><I>the journey begins... </I></B></a></td>
<td rowspan="2" style="background-attachment: fixed"><img src="{% static 'allocation/logo.png' %}" width="30%" alt="logo"></td>
</tr>
</table>
</table> -->
<img src ="{% static 'allocation/logo.png' %}" class="fixed" width="20%" height="20%" alt="logo" >
<div class="container">
<div class="content"><h1 align="center" style="color:black">General Allocation Portal</h1></div>
</div>
<div class="tool1" style="margin-top: 29%; text-align: center; font-size: 30px;">
<div class="tool1" style="margin-top: 52%;">
</div>
<div class="tool2" style="margin-top: 10px; text-align: center; font-size: 50px; color: white">
<a href = "/allocation/admin">
<div class="tool2" style="margin-top: 10px; text-align: center; height: 60px; color: white">
<a href = "/allocation/admin" style="font-size: 40px;">
Institute login
</a>
</div>
<div class="tool3" style="margin-top: 5px; text-align: center; font-size: 50px; color:white">
<a href="/allocation">
<div class="tool3" style="margin-top: 5px; text-align: center; height: 60px; color:white">
<a href="/allocation" style="font-size: 40px">
Applicant login
</a>
</div>
<div class="tool4" style="margin-top: 5px; text-align: center; font-size: 50px; color:white">
<a href="/allocation/register">
<div class="tool4" style="margin-top: 5px; text-align: center; height: 60px; color:white">
<a href="/allocation/register" style="font-size: 40px">
Register with us
</a>
</div>
......
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