From cb52e1a47572e2eccb938294791a05daf246a98f Mon Sep 17 00:00:00 2001 From: Gowtham Date: Thu, 16 Dec 2021 23:05:04 +0530 Subject: [PATCH 1/3] Modified APIs --- CDC_Backend/APIs/admin.py | 16 ++++++++++++--- CDC_Backend/APIs/adminViews.py | 8 +++++--- CDC_Backend/APIs/companyViews.py | 2 ++ CDC_Backend/APIs/models.py | 11 ++++++++++- CDC_Backend/APIs/serializers.py | 7 +++++-- CDC_Backend/APIs/studentViews.py | 2 +- CDC_Backend/APIs/utils.py | 6 ++++-- CDC_Backend/CDC_Backend/settings.py | 30 ++++++++++++++--------------- 8 files changed, 55 insertions(+), 27 deletions(-) diff --git a/CDC_Backend/APIs/admin.py b/CDC_Backend/APIs/admin.py index eb4711c..a5a0a6d 100644 --- a/CDC_Backend/APIs/admin.py +++ b/CDC_Backend/APIs/admin.py @@ -8,10 +8,7 @@ from django.utils.safestring import SafeText from .models import * admin.site.register(User) -# admin.site.register(Student) admin.site.register(Admin) -# admin.site.register(Placement) -admin.site.register(PlacementApplication) admin.site.register(PrePlacementOffer) admin.site.site_header = "CDC Recruitment Portal" @@ -38,4 +35,17 @@ class Placement(admin.ModelAdmin): list_filter = ('tier',) +@admin.register(PlacementApplication) +class PlacementApplication(admin.ModelAdmin): + list_display = ('id', 'Placement', 'Student', 'selected') + search_fields = ('id',) + ordering = ('id',) + list_filter = ('selected',) + + def Placement(self, obj): + return model_admin_url(obj.placement) + + def Student(self, obj): + return model_admin_url(obj.student) + diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index 845ecef..3183343 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -53,13 +53,15 @@ def markStatus(request, id, email, user_type): def getDashboard(request, id, email, user_type): try: placements = Placement.objects.all().order_by('-created_at') - ongoing = placements.filter(deadline_datetime__gt=datetime.now()) - previous = placements.exclude(deadline_datetime__gt=datetime.now()) + ongoing = placements.filter(deadline_datetime__gt=datetime.now(), offer_accepted__isnull=False) + previous = placements.exclude(deadline_datetime__gt=datetime.now()).filter(offer_accepted__isnull=False) + new = placements.filter(offer_accepted__isnull=True) ongoing = PlacementSerializerForAdmin(ongoing, many=True).data previous = PlacementSerializerForAdmin(previous, many=True).data + new = PlacementSerializerForAdmin(new, many=True).data return Response( - {'action': "Get Dashboard - Admin", 'message': "Data Found", "ongoing": ongoing, "previous": previous}, + {'action': "Get Dashboard - Admin", 'message': "Data Found", "ongoing": ongoing, "previous": previous, "new": new}, status=status.HTTP_200_OK) except Http404: return Response({'action': "Get Dashboard - Admin", 'message': 'Student Not Found'}, diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index 7d7d50b..a73b0cf 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -193,6 +193,8 @@ def addPlacement(request): # Check if tentative_no_of_offers is integer if data[TENTATIVE_NO_OF_OFFERS].isdigit(): opening.tentative_no_of_offers = int(data[TENTATIVE_NO_OF_OFFERS]) + elif data[TENTATIVE_NO_OF_OFFERS] == 'null': + opening.tentative_no_of_offers = None else: raise ValueError('Tentative No Of Offers must be an integer') diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index d8c9080..b5022b9 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -22,6 +22,9 @@ class Student(models.Model): resumes = ArrayField(models.CharField(null=True, default=None, max_length=100), size=10, default=list, blank=True) cpi = models.DecimalField(decimal_places=2, max_digits=4) + def __str__(self): + return str(self.roll_no) + class Admin(models.Model): id = models.CharField(blank=False, max_length=15, primary_key=True) @@ -81,7 +84,7 @@ class Placement(models.Model): size=TOTAL_BRANCHES, default=list ) - tentative_no_of_offers = models.IntegerField(blank=False, default=1) + tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) other_requirements = models.CharField(blank=True, max_length=200, default="") additional_info = ArrayField(models.CharField(blank=True, max_length=200), size=15, default=list, blank=True) email_verified = models.BooleanField(blank=False, default=False) @@ -96,6 +99,9 @@ class Placement(models.Model): return super(Placement, self).save(*args, **kwargs) + def __str__(self): + return self.company_name + " - " + self.id + class PlacementApplication(models.Model): id = models.CharField(blank=False, primary_key=True, max_length=15) placement = models.ForeignKey(Placement, blank=False, on_delete=models.RESTRICT, default=None, null=True) @@ -116,6 +122,9 @@ class PlacementApplication(models.Model): verbose_name_plural = "Placement Applications" unique_together = ('placement_id', 'student_id') + def __str__(self): + return self.placement.company_name + " - " + self.student.name + class PrePlacementOffer(models.Model): id = models.AutoField(primary_key=True) diff --git a/CDC_Backend/APIs/serializers.py b/CDC_Backend/APIs/serializers.py index a7c1228..98608a3 100644 --- a/CDC_Backend/APIs/serializers.py +++ b/CDC_Backend/APIs/serializers.py @@ -154,8 +154,11 @@ class PlacementApplicationSerializer(serializers.ModelSerializer): return data def get_resume_link(self, obj): - link = LINK_TO_STORAGE_RESUME + urllib.parse.quote_plus(obj.id + "/" + obj.resume) - return link + ele = {} + ele['link'] = LINK_TO_STORAGE_RESUME + urllib.parse.quote_plus(obj.id + "/" + obj.resume) + ele['name'] = obj.resume + return ele + class Meta: model = PlacementApplication diff --git a/CDC_Backend/APIs/studentViews.py b/CDC_Backend/APIs/studentViews.py index 79504fc..946e52f 100644 --- a/CDC_Backend/APIs/studentViews.py +++ b/CDC_Backend/APIs/studentViews.py @@ -44,7 +44,7 @@ def addResume(request, id, email, user_type): files = request.FILES file = files['file'] - destination_path = STORAGE_DESTINATION_RESUMES + id + "/" + destination_path = STORAGE_DESTINATION_RESUMES + str(student.roll_no) + "/" file_name = saveFile(file, destination_path) student.resumes.append(file_name) diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index b35dd17..de58aae 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -1,6 +1,7 @@ import logging import os import random +import re import string import sys from os import path, remove @@ -113,8 +114,10 @@ def saveFile(file, location): prefix = generateRandomString() file_name = prefix + "_" + file.name + file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name) + if not path.isdir(location): - os.mkdir(location) + os.makedirs(location) destination_path = location + str(file_name) if path.exists(destination_path): @@ -123,7 +126,6 @@ def saveFile(file, location): with open(destination_path, 'wb+') as destination: for chunk in file.chunks(): destination.write(chunk) - return file_name diff --git a/CDC_Backend/CDC_Backend/settings.py b/CDC_Backend/CDC_Backend/settings.py index 8219a0f..d524b5b 100644 --- a/CDC_Backend/CDC_Backend/settings.py +++ b/CDC_Backend/CDC_Backend/settings.py @@ -83,23 +83,23 @@ WSGI_APPLICATION = 'CDC_Backend.wsgi.application' # https://docs.djangoproject.com/en/2.2/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': os.environ.get("DB_NAME"), - 'USER': os.environ.get("DB_USER"), - 'PASSWORD': os.environ.get("DB_PASSWORD"), - 'HOST': os.environ.get("DB_HOST"), - 'PORT': os.environ.get("DB_PORT"), - }, - # 'default': { # 'ENGINE': 'django.db.backends.postgresql_psycopg2', - # 'NAME': 'd84i5cbjig5rrf', - # 'USER': 'hbkullcdjbxuwh', - # 'PASSWORD': '45d990da00e2cc96d7d4e2e5e308d4b07a387883f70c40e090a6252175cb634e', - # 'HOST': 'ec2-54-163-97-228.compute-1.amazonaws.com', - # 'PORT': '5432', - # } + # 'NAME': os.environ.get("DB_NAME"), + # 'USER': os.environ.get("DB_USER"), + # 'PASSWORD': os.environ.get("DB_PASSWORD"), + # 'HOST': os.environ.get("DB_HOST"), + # 'PORT': os.environ.get("DB_PORT"), + # }, + + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'd84i5cbjig5rrf', + 'USER': 'hbkullcdjbxuwh', + 'PASSWORD': '45d990da00e2cc96d7d4e2e5e308d4b07a387883f70c40e090a6252175cb634e', + 'HOST': 'ec2-54-163-97-228.compute-1.amazonaws.com', + 'PORT': '5432', + } } # Password validation From 4dbd4a65c8fd9b8346fc37422403a8a89c8581cb Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:15:56 +0530 Subject: [PATCH 2/3] Added Verify Email Functionality --- CDC_Backend/APIs/adminViews.py | 2 +- CDC_Backend/APIs/companyUrls.py | 1 + CDC_Backend/APIs/companyViews.py | 59 ++++++++++++++++--- CDC_Backend/APIs/constants.py | 12 ++-- CDC_Backend/APIs/utils.py | 21 ++++++- ...l.html => company_email_verification.html} | 6 +- .../templates/company_opening_submitted.html | 2 +- ...udent_application_status_not_selected.html | 2 +- .../student_application_status_selected.html | 2 +- .../student_application_submitted.html | 2 +- requirements.txt | 1 + 11 files changed, 89 insertions(+), 21 deletions(-) rename CDC_Backend/templates/{verify_email.html => company_email_verification.html} (91%) diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index 3183343..dc50652 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -16,7 +16,7 @@ def markStatus(request, id, email, user_type): # Getting all application from db for this opening applications = PlacementApplication.objects.filter(placement_id=data[OPENING_ID]) for i in data[STUDENT_LIST]: - application = applications.filter(student_id=i[STUDENT_ID]) # Filtering student's application + application = applications.filter(student__roll_no=i[STUDENT_ID]) # Filtering student's application if len(application) > 0: application = application[0] application.selected = True if i[STUDENT_SELECTED] == "true" else False diff --git a/CDC_Backend/APIs/companyUrls.py b/CDC_Backend/APIs/companyUrls.py index 5cda889..525a585 100644 --- a/CDC_Backend/APIs/companyUrls.py +++ b/CDC_Backend/APIs/companyUrls.py @@ -4,4 +4,5 @@ from . import companyViews urlpatterns = [ path('addPlacement/', companyViews.addPlacement, name="Add Placement"), + path('verifyEmail/', companyViews.verifyEmail, name="Verify Email"), ] diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index a73b0cf..862483f 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -1,5 +1,5 @@ import json -from datetime import datetime +import datetime from rest_framework.decorators import api_view @@ -178,7 +178,7 @@ def addPlacement(request): else: raise ValueError('Invalid compensation gross') # Convert to date object - opening.tentative_date_of_joining = datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], '%d-%m-%Y').date() + opening.tentative_date_of_joining = datetime.datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], '%d-%m-%Y').date() # Only Allowing Fourth Year for Placement opening.allowed_batch = [FOURTH_YEAR, ] @@ -202,15 +202,18 @@ def addPlacement(request): opening.save() + + + stat, link = generateOneTimeVerificationLink(opening.email, opening.id, "Placement") + if not stat: + raise RuntimeError("Error in generating one time verification link for placement") data = { "designation": opening.designation, - "opening_type": PLACEMENT, - "opening_link": PLACEMENT_OPENING_URL.format(id=opening.id), # Some Changes here too - "company_name": opening.company_name + "one_time_link": link } - sendEmail(opening.email, COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data, - COMPANY_OPENING_SUBMITTED_TEMPLATE) + sendEmail(opening.email, COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT, data, + COMPANY_EMAIL_VERIFICATION_TEMPLATE) return Response({'action': "Add Placement", 'message': "Placement Added Successfully"}, status=status.HTTP_200_OK) @@ -222,3 +225,45 @@ def addPlacement(request): logger.warning("Add New Placement: " + str(sys.exc_info())) return Response({'action': "Add Placement", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +@precheck([TOKEN]) +def verifyEmail(request): + try: + data = request.data + token = data[TOKEN] + # decode token + decoded_token = jwt.decode(token, os.environ.get("EMAIL_VERIFICATION_SECRET_KEY"), algorithms=['HS256']) + # get email, opening_id, opening_type from token + email = decoded_token['email'] + opening_id = decoded_token['opening_id'] + opening_type = decoded_token['opening_type'] + # get opening based on opening_type and opening_id + if opening_type == PLACEMENT: + opening = get_object_or_404(Placement, id=opening_id) + if email != opening.email: + raise ValueError("Invalid Email") + opening.email_verified = True + opening.save() + data = { + "designation": opening.designation, + "opening_type": PLACEMENT, + "opening_link": PLACEMENT_OPENING_URL.format(id=opening.id), # Some Changes here too + "company_name": opening.company_name + } + sendEmail(opening.email, COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data, + COMPANY_OPENING_SUBMITTED_TEMPLATE) + else: + raise ValueError('Invalid opening type') + return Response({'action': "Verify Email", 'message': "Email Verified Successfully"}, + status=status.HTTP_200_OK) + except Http404: + return Response({'action': "Verify Email", 'message': "Opening Not Found"}, + status=status.HTTP_404_NOT_FOUND) + except ValueError as e: + return Response({'action': "Verify Email", 'message': str(e)}, + status=status.HTTP_400_BAD_REQUEST) + except: + logger.warning("Verify Email: " + str(sys.exc_info())) + return Response({'action': "Verify Email", 'message': "Something went wrong"}, + status=status.HTTP_400_BAD_REQUEST) diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index 4201ce9..af96560 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -39,13 +39,12 @@ TOTAL_BATCHES = 4 # Total No of Batches CLIENT_ID = "956830229554-290mirc16pdhd5j7ph7v7ukibo4t1qcp.apps.googleusercontent.com" # Google Login Client ID # To be Configured Properly -PLACEMENT_OPENING_URL = "https://www.googleapis.com/auth/adwords/{id}" +PLACEMENT_OPENING_URL = "https://www.googleapis.com/auth/adwords/{id}" # On frontend, this is the URL to be opened LINK_TO_STORAGE_COMPANY_ATTACHMENT = "https://storage.googleapis.com/cdc-backend-attachments/company_attachments/" LINK_TO_STORAGE_RESUME = "https://storage.googleapis.com/cdc-backend-attachments/resume/" LINK_TO_APPLICATIONS_CSV = "https://storage.googleapis.com/cdc-backend-attachments/applications-csv/" +LINK_TO_EMAIl_VERIFICATION_API = "https://api.sendgrid.com/v3/mail/send?token={token}" - -TOKEN = "token_id" EMAIL = "email" STUDENT = 'student' @@ -55,13 +54,14 @@ COMPANY = '' # To be Configured Properly FOURTH_YEAR = '2018' MAX_OFFERS_PER_STUDENT = 2 +EMAIL_VERIFICATION_TOKEN_TTL = 48 # in hours STORAGE_DESTINATION_RESUMES = "./Storage/Resumes/" STORAGE_DESTINATION_COMPANY_ATTACHMENTS = './Storage/Company_Attachments/' STORAGE_DESTINATION_APPLICATION_CSV = './Storage/Application_CSV/' - +TOKEN = 'token' RESUME_FILE_NAME = 'resume_file_name' APPLICATION_ID = "application_id" @@ -123,14 +123,16 @@ STUDENT_ID = "student_id" STUDENT_SELECTED = "student_selected" -COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT = "Notification Submitted - {id} - CDC IIT Dharwad" +COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT = "Notification Submitted - {id} - Career Development Cell, IIT Dharwad" STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT = 'Application Status : {company_name} - {id}' STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT = 'CDC - Application Submitted - {company_name}' +COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT = 'Email Verification - Career Development Cell, IIT Dharwad' STUDENT_APPLICATION_SUBMITTED_TEMPLATE = 'student_application_submitted.html' COMPANY_OPENING_SUBMITTED_TEMPLATE = 'company_opening_submitted.html' STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE = 'student_application_status_selected.html' STUDENT_APPLICATION_STATUS_NOT_SELECTED_TEMPLATE = 'student_application_status_not_selected.html' +COMPANY_EMAIL_VERIFICATION_TEMPLATE = 'company_email_verification.html' APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI', 'Resume', 'Selected', ] diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index de58aae..382e995 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -1,9 +1,11 @@ +import datetime import logging import os import random import re import string import sys +import jwt from os import path, remove import background_task @@ -104,7 +106,7 @@ def isAuthorized(allowed_users=None): def generateRandomString(): try: N = 15 - res = ''.join(random.choices(string.ascii_uppercase +string.ascii_lowercase+ string.digits, k=N)) + res = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=N)) return res except: return False @@ -214,3 +216,20 @@ def getTier(compensation_gross, is_psu=False): print(sys.exc_info()) logger.warning("Utils - getTier: " + str(sys.exc_info())) return False, "_" + + +def generateOneTimeVerificationLink(email, opening_id, opening_type): + try: + token_payload = { + "email": email, + "opening_id": opening_id, + "opening_type": opening_type, + 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=EMAIL_VERIFICATION_TOKEN_TTL) + } + token = jwt.encode(token_payload, os.environ.get("EMAIL_VERIFICATION_SECRET_KEY"), algorithm="HS256") + link = LINK_TO_EMAIl_VERIFICATION_API.format(token=token) + return True, link + except: + print(sys.exc_info()) + logger.warning("Utils - generateOneTimeVerificationLink: " + str(sys.exc_info())) + return False, "_" diff --git a/CDC_Backend/templates/verify_email.html b/CDC_Backend/templates/company_email_verification.html similarity index 91% rename from CDC_Backend/templates/verify_email.html rename to CDC_Backend/templates/company_email_verification.html index d12d078..e3f480a 100644 --- a/CDC_Backend/templates/verify_email.html +++ b/CDC_Backend/templates/company_email_verification.html @@ -32,7 +32,7 @@ style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;"> - + @@ -41,9 +41,9 @@ style="width:100%;border-collapse:collapse;border:0;border-spacing:0;"> -

Hi,

+

- We have received your Job Notification for {{designation}}. Kindly verify your email by clicking here. + We have received your Job Notification. Kindly verify your email by clicking here.

diff --git a/CDC_Backend/templates/company_opening_submitted.html b/CDC_Backend/templates/company_opening_submitted.html index 88147e0..a37c107 100644 --- a/CDC_Backend/templates/company_opening_submitted.html +++ b/CDC_Backend/templates/company_opening_submitted.html @@ -32,7 +32,7 @@ style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;"> - + diff --git a/CDC_Backend/templates/student_application_status_not_selected.html b/CDC_Backend/templates/student_application_status_not_selected.html index ee01642..4adcd2d 100644 --- a/CDC_Backend/templates/student_application_status_not_selected.html +++ b/CDC_Backend/templates/student_application_status_not_selected.html @@ -31,7 +31,7 @@ style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;"> - + diff --git a/CDC_Backend/templates/student_application_status_selected.html b/CDC_Backend/templates/student_application_status_selected.html index 0cd439f..608268a 100644 --- a/CDC_Backend/templates/student_application_status_selected.html +++ b/CDC_Backend/templates/student_application_status_selected.html @@ -31,7 +31,7 @@ style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;"> - + diff --git a/CDC_Backend/templates/student_application_submitted.html b/CDC_Backend/templates/student_application_submitted.html index eaeb123..05e5be8 100644 --- a/CDC_Backend/templates/student_application_submitted.html +++ b/CDC_Backend/templates/student_application_submitted.html @@ -32,7 +32,7 @@ style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;"> - + diff --git a/requirements.txt b/requirements.txt index bdb3ad7..fc2002f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,6 +28,7 @@ pyasn1-modules==0.2.8 pylint==2.12.2 python-dotenv==0.19.2 pytz==2021.3 +PyJWT==2.0.1 requests==2.26.0 rsa==4.8 six==1.16.0 From 32c6468ade0fee24e3c6ee176515ea2d8d3bb937 Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Fri, 17 Dec 2021 19:23:32 +0530 Subject: [PATCH 3/3] Fixed Bugs --- CDC_Backend/APIs/adminViews.py | 46 +++++++++++++++++--------------- CDC_Backend/APIs/companyViews.py | 7 +++-- CDC_Backend/APIs/utils.py | 2 +- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index dc50652..014d79c 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -1,10 +1,10 @@ -import json -from datetime import datetime - -from .utils import * -from rest_framework.decorators import api_view import csv +import json + +from rest_framework.decorators import api_view + from .serializers import * +from .utils import * @api_view(['POST']) @@ -22,8 +22,9 @@ def markStatus(request, id, email, user_type): application.selected = True if i[STUDENT_SELECTED] == "true" else False email = str(application.student.roll_no) + "@iitdh.ac.in" # Only allowing for IITDh emails - subject = STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT.format(company_name=application.placement.company_name, - id=application.id) + subject = STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT.format( + company_name=application.placement.company_name, + id=application.id) data = { "company_name": application.placement.company_name, "designation": application.placement.designation, @@ -53,15 +54,17 @@ def markStatus(request, id, email, user_type): def getDashboard(request, id, email, user_type): try: placements = Placement.objects.all().order_by('-created_at') - ongoing = placements.filter(deadline_datetime__gt=datetime.now(), offer_accepted__isnull=False) - previous = placements.exclude(deadline_datetime__gt=datetime.now()).filter(offer_accepted__isnull=False) + ongoing = placements.filter(deadline_datetime__gt=datetime.datetime.now(), offer_accepted__isnull=False) + previous = placements.exclude(deadline_datetime__gt=datetime.datetime.now()).filter( + offer_accepted__isnull=False) new = placements.filter(offer_accepted__isnull=True) ongoing = PlacementSerializerForAdmin(ongoing, many=True).data previous = PlacementSerializerForAdmin(previous, many=True).data new = PlacementSerializerForAdmin(new, many=True).data return Response( - {'action': "Get Dashboard - Admin", 'message': "Data Found", "ongoing": ongoing, "previous": previous, "new": new}, + {'action': "Get Dashboard - Admin", 'message': "Data Found", "ongoing": ongoing, "previous": previous, + "new": new}, status=status.HTTP_200_OK) except Http404: return Response({'action': "Get Dashboard - Admin", 'message': 'Student Not Found'}, @@ -80,7 +83,7 @@ def updateDeadline(request, id, email, user_type): data = request.data opening = get_object_or_404(Placement, pk=data[OPENING_ID]) # Updating deadline date with correct format in datetime field - opening.deadline_datetime = datetime.strptime(data[DEADLINE_DATETIME], '%Y-%m-%d %H:%M:%S %z') + opening.deadline_datetime = datetime.datetime.strptime(data[DEADLINE_DATETIME], '%Y-%m-%d %H:%M:%S %z') opening.save() return Response({'action': "Update Deadline", 'message': "Deadline Updated"}, status=status.HTTP_200_OK) @@ -92,6 +95,7 @@ def updateDeadline(request, id, email, user_type): return Response({'action': "Update Deadline", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + @api_view(['POST']) @isAuthorized([ADMIN]) @precheck([OPENING_ID, OFFER_ACCEPTED]) @@ -111,6 +115,7 @@ def updateOfferAccepted(request, id, email, user_type): return Response({'action': "Update Offer Accepted", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + @api_view(['POST']) @isAuthorized([ADMIN]) @precheck([OPENING_ID, EMAIL_VERIFIED]) @@ -130,6 +135,7 @@ def updateEmailVerified(request, id, email, user_type): return Response({'action': "Update Email Verified", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + @api_view(['POST']) @isAuthorized([ADMIN]) @precheck([OPENING_ID, ADDITIONAL_INFO]) @@ -167,8 +173,8 @@ def getApplications(request, id, email, user_type): opening = get_object_or_404(Placement, pk=data[OPENING_ID]) applications = PlacementApplication.objects.filter(placement=opening) serializer = PlacementApplicationSerializerForAdmin(applications, many=True) - return Response({'action': "Get Applications", 'message': 'Data Found', 'applications':serializer.data}, - status=status.HTTP_200_OK) + return Response({'action': "Get Applications", 'message': 'Data Found', 'applications': serializer.data}, + status=status.HTTP_200_OK) except Http404: return Response({'action': "Get Applications", 'message': 'Opening Not Found'}, status=status.HTTP_404_NOT_FOUND) @@ -178,7 +184,6 @@ def getApplications(request, id, email, user_type): status=status.HTTP_400_BAD_REQUEST) - @api_view(['POST']) @isAuthorized(allowed_users=[ADMIN]) @precheck(required_data=[OPENING_TYPE, OPENING_ID, RESUME_FILE_NAME, @@ -195,7 +200,7 @@ def submitApplication(request, id, email, user_type): opening = get_object_or_404(Placement, id=data[OPENING_ID], allowed_batch__contains=[student.batch], allowed_branch__contains=[student.branch], - deadline_datetime__gte=datetime.now().date() + deadline_datetime__gte=datetime.datetime.now().date() ) if not opening.offer_accepted or not opening.email_verified: raise PermissionError("Placement Not Approved") @@ -231,7 +236,7 @@ def submitApplication(request, id, email, user_type): "additional_info": dict(json.loads(application.additional_info)), } subject = STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT.format(company_name=opening.company_name) - student_email = str(student.roll_no)+"@iitdh.ac.in" + student_email = str(student.roll_no) + "@iitdh.ac.in" sendEmail(student_email, subject, data, STUDENT_APPLICATION_SUBMITTED_TEMPLATE) application.save() @@ -252,7 +257,6 @@ def submitApplication(request, id, email, user_type): status=status.HTTP_400_BAD_REQUEST) - @api_view(['POST']) @isAuthorized(allowed_users=[ADMIN]) @precheck(required_data=[OPENING_ID]) @@ -272,12 +276,12 @@ def generateCSV(request, id, email, user_type): header_row.extend(placement.additional_info) writer.writerow(header_row) for apl in applications: - row_details=[] + row_details = [] row_details.append(apl.applied_at) row_details.append(apl.student.roll_no) row_details.append(apl.student.name) - row_details.append(str(apl.student.roll_no)+"@iitdh.ac.in") + row_details.append(str(apl.student.roll_no) + "@iitdh.ac.in") row_details.append(apl.student.phone_number) row_details.append(apl.student.branch) row_details.append(apl.student.batch) @@ -291,11 +295,11 @@ def generateCSV(request, id, email, user_type): writer.writerow(row_details) f.close() - file_path = LINK_TO_APPLICATIONS_CSV + urllib.parse.quote_plus(filename+".csv") + file_path = LINK_TO_APPLICATIONS_CSV + urllib.parse.quote_plus(filename + ".csv") return Response({'action': "Create csv", 'message': "CSV created", 'file': file_path}, status=status.HTTP_200_OK) except: logger.warning("Create csv: " + str(sys.exc_info())) print(sys.exc_info()) return Response({'action': "Create csv", 'message': "Error Occurred"}, - status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file + status=status.HTTP_400_BAD_REQUEST) diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index 862483f..b133b81 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -1,5 +1,4 @@ import json -import datetime from rest_framework.decorators import api_view @@ -178,7 +177,8 @@ def addPlacement(request): else: raise ValueError('Invalid compensation gross') # Convert to date object - opening.tentative_date_of_joining = datetime.datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], '%d-%m-%Y').date() + opening.tentative_date_of_joining = datetime.datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], + '%d-%m-%Y').date() # Only Allowing Fourth Year for Placement opening.allowed_batch = [FOURTH_YEAR, ] @@ -202,8 +202,6 @@ def addPlacement(request): opening.save() - - stat, link = generateOneTimeVerificationLink(opening.email, opening.id, "Placement") if not stat: raise RuntimeError("Error in generating one time verification link for placement") @@ -226,6 +224,7 @@ def addPlacement(request): return Response({'action': "Add Placement", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + @api_view(['POST']) @precheck([TOKEN]) def verifyEmail(request): diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index 382e995..d00e35c 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -5,10 +5,10 @@ import random import re import string import sys -import jwt from os import path, remove import background_task +import jwt from django.conf import settings from django.core.mail import EmailMultiAlternatives from django.http import Http404