Merge branch 'main' into offer_status

This commit is contained in:
karthikmurakonda 2023-06-27 03:28:50 +05:30
commit 8aa393033d
19 changed files with 239 additions and 16 deletions

BIN
.DS_Store vendored

Binary file not shown.

4
.gitignore vendored
View File

@ -140,6 +140,10 @@ dmypy.json
.idea .idea
*.pyc *.pyc
dev.env dev.env
.vscode/settings.json
#vscode settings
.vscode/
#vscode settings #vscode settings
.vscode/ .vscode/

BIN
CDC_Backend/.DS_Store vendored

Binary file not shown.

View File

@ -5,4 +5,5 @@ from . import companyViews
urlpatterns = [ urlpatterns = [
path('addPlacement/', companyViews.addPlacement, name="Add Placement"), path('addPlacement/', companyViews.addPlacement, name="Add Placement"),
path('verifyEmail/', companyViews.verifyEmail, name="Verify Email"), path('verifyEmail/', companyViews.verifyEmail, name="Verify Email"),
path('getAutoFillJnf/', companyViews.autoFillJnf, name="Auto FIll JNF"),
] ]

View File

@ -1,6 +1,7 @@
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from .utils import * from .utils import *
from .serializers import *
logger = logging.getLogger('db') logger = logging.getLogger('db')
@ -283,7 +284,8 @@ def verifyEmail(request):
"opening_type": PLACEMENT, "opening_type": PLACEMENT,
"company_name": opening.company_name, "company_name": opening.company_name,
} }
sendEmail([opening.email, CDC_MAIl_ADDRESS], COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data, sendEmail([opening.email, CDC_MAIl_ADDRESS],
COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data,
COMPANY_OPENING_SUBMITTED_TEMPLATE, attachment_jnf_respone) COMPANY_OPENING_SUBMITTED_TEMPLATE, attachment_jnf_respone)
return Response({'action': "Verify Email", 'message': "Email Verified Successfully"}, return Response({'action': "Verify Email", 'message': "Email Verified Successfully"},
@ -298,3 +300,23 @@ def verifyEmail(request):
logger.warning("Verify Email: " + str(sys.exc_info())) logger.warning("Verify Email: " + str(sys.exc_info()))
return Response({'action': "Verify Email", 'message': "Something went wrong"}, return Response({'action': "Verify Email", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET'])
@precheck([PLACEMENT_ID])
def autoFillJnf(request):
try:
data = request.GET
placement_id = data.get(PLACEMENT_ID)
opening = get_object_or_404(Placement, id=placement_id)
serializer = AutofillSerializers(opening)
return Response({'action': "Get AutoFill", 'message': 'Data Found', 'placement_data': serializer.data},
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Get AutoFill", 'message': 'Placement Not Found'},
status=status.HTTP_404_NOT_FOUND)
except Exception as e:
traceback_str = traceback.format_exc()
logger.warning("Get AutoFill: " + traceback_str)
return Response({'action': "Get AutoFill", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST)

View File

@ -49,6 +49,9 @@ CDC_MAIl_ADDRESS = 'cdc@iitdh.ac.in'
# To be Configured Properly # To be Configured Properly
CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID
CLIENT_SECRET = os.environ.get('GOOGLE_OAUTH_CLIENT_SECRET') # Google Login Client Secret
REDIRECT_URI = 'postmessage' # Google Login Redirect URI
OAUTH2_API_ENDPOINT = 'https://oauth2.googleapis.com/token' # Google Login OAUTH2 URL
# To be Configured Properly # To be Configured Properly
PLACEMENT_OPENING_URL = "https://cdc.iitdh.ac.in/portal/student/dashboard/placements/{id}" # On frontend, this is the URL to be opened PLACEMENT_OPENING_URL = "https://cdc.iitdh.ac.in/portal/student/dashboard/placements/{id}" # On frontend, this is the URL to be opened
@ -58,6 +61,9 @@ LINK_TO_APPLICATIONS_CSV = "https://cdc.iitdh.ac.in/storage/Application_CSV/"
LINK_TO_EMAIl_VERIFICATION_API = "https://cdc.iitdh.ac.in/portal/company/verifyEmail?token={token}" LINK_TO_EMAIl_VERIFICATION_API = "https://cdc.iitdh.ac.in/portal/company/verifyEmail?token={token}"
PDF_FILES_SERVING_ENDPOINT = 'https://cdc.iitdh.ac.in/storage/Company_Attachments/' # TODO: Change this to actual URL PDF_FILES_SERVING_ENDPOINT = 'https://cdc.iitdh.ac.in/storage/Company_Attachments/' # TODO: Change this to actual URL
AUTH_CODE = "code"
ID_TOKEN = "id_token"
REFRESH_TOKEN = "refresh_token"
EMAIL = "email" EMAIL = "email"
STUDENT = 'student' STUDENT = 'student'
@ -90,6 +96,7 @@ FIELD = "field"
STATUS_ACCEPTING_APPLICATIONS = "Accepting Applications" STATUS_ACCEPTING_APPLICATIONS = "Accepting Applications"
PLACEMENT = "Placement" PLACEMENT = "Placement"
PLACEMENT_ID = "placement_id"
COMPANY_NAME = "company_name" COMPANY_NAME = "company_name"
ADDRESS = "address" ADDRESS = "address"
@ -158,7 +165,7 @@ STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT = 'CDC - Application Submitted -
STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT = 'CDC - Application Updated - {company_name}' STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT = 'CDC - Application Updated - {company_name}'
COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT = 'Email Verification - Career Development Cell, IIT Dharwad' COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT = 'Email Verification - Career Development Cell, IIT Dharwad'
NOTIFY_STUDENTS_OPENING_TEMPLATE_SUBJECT = 'Placement Opportunity at {company_name}' NOTIFY_STUDENTS_OPENING_TEMPLATE_SUBJECT = 'Placement Opportunity at {company_name}'
REMINDER_STUDENTS_OPENING_TEMPLATE_SUBJECT = 'Reminder - Placement Opportunity at {company_name}'
STUDENT_APPLICATION_SUBMITTED_TEMPLATE = 'student_application_submitted.html' STUDENT_APPLICATION_SUBMITTED_TEMPLATE = 'student_application_submitted.html'
COMPANY_OPENING_SUBMITTED_TEMPLATE = 'company_opening_submitted.html' COMPANY_OPENING_SUBMITTED_TEMPLATE = 'company_opening_submitted.html'
STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE = 'student_application_status_selected.html' STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE = 'student_application_status_selected.html'
@ -167,7 +174,7 @@ STUDENT_APPLICATION_UPDATED_TEMPLATE = 'student_application_updated.html'
COMPANY_EMAIL_VERIFICATION_TEMPLATE = 'company_email_verification.html' COMPANY_EMAIL_VERIFICATION_TEMPLATE = 'company_email_verification.html'
COMPANY_JNF_RESPONSE_TEMPLATE = 'company_jnf_response.html' COMPANY_JNF_RESPONSE_TEMPLATE = 'company_jnf_response.html'
NOTIFY_STUDENTS_OPENING_TEMPLATE = 'notify_students_new_opening.html' NOTIFY_STUDENTS_OPENING_TEMPLATE = 'notify_students_new_opening.html'
REMINDER_STUDENTS_OPENING_TEMPLATE = 'students_opening_reminder.html'
APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI', APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI',
'Resume', 'Selected', ] 'Resume', 'Selected', ]

View File

@ -188,4 +188,11 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer):
class ContributorSerializer(serializers.ModelSerializer): class ContributorSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Contributor model = Contributor
class AutofillSerializers(serializers.ModelSerializer):
class Meta:
model = Placement
fields = '__all__'

View File

@ -7,15 +7,42 @@ logger = logging.getLogger('db')
@api_view(['POST']) @api_view(['POST'])
@precheck(required_data=[AUTH_CODE])
@get_token()
@isAuthorized(allowed_users='*') @isAuthorized(allowed_users='*')
def login(request, id, email, user_type): def login(request, id, email, user_type, token, refresh_token):
try: try:
return Response({'action': "Login", 'message': "Verified", "user_type": user_type}, return Response({'action': "Login", 'message': "Verified", "user_type": user_type, "id_token": token, "refresh_token": refresh_token},
status=status.HTTP_200_OK) status=status.HTTP_200_OK)
except: except:
return Response({'action': "Login", 'message': "Something Went Wrong"}, return Response({'action': "Login", 'message': "Something Went Wrong"},
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@precheck(required_data=[REFRESH_TOKEN])
def refresh(request):
refresh_token = request.data[REFRESH_TOKEN]
data = {
'refresh_token': refresh_token,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'refresh_token'
}
response = rq.post(OAUTH2_API_ENDPOINT, data=data)
if response.status_code == 200:
id_info = id_token.verify_oauth2_token(response.json()['id_token'], requests.Request(), CLIENT_ID)
if id_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
raise ValueError('Wrong issuer.')
user_types = User.objects.filter(email=id_info['email']).values_list('user_type', flat=True)
return Response({'action': "Refresh Token", 'message': "Token Refreshed", "id_token": response.json()['id_token'], "user_type": user_types[0]},
status=status.HTTP_200_OK)
else:
logger.error("refresh_token"+str(response))
return Response({'action': "Refresh Token", 'message': "Something Went Wrong"},
status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET']) @api_view(['GET'])
@isAuthorized(allowed_users=[STUDENT]) @isAuthorized(allowed_users=[STUDENT])

View File

@ -4,6 +4,7 @@ from . import studentViews, studentUrls, companyUrls, adminUrls
urlpatterns = [ urlpatterns = [
path('login/', studentViews.login, name="Login"), path('login/', studentViews.login, name="Login"),
path('refresh_token/', studentViews.refresh, name="Refresh Token"),
path('student/', include(studentUrls)), path('student/', include(studentUrls)),
path('company/', include(companyUrls)), path('company/', include(companyUrls)),
path('admin/', include(adminUrls)), path('admin/', include(adminUrls)),

View File

@ -33,6 +33,38 @@ from .models import User, PrePlacementOffer, PlacementApplication, Placement, St
logger = logging.getLogger('db') logger = logging.getLogger('db')
def get_token():
def decorator(view_func):
def wrapper_func(request, *args, **kwargs):
try:
authcode = request.data[AUTH_CODE]
data = {
'code': authcode,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'authorization_code'
}
r = rq.post(OAUTH2_API_ENDPOINT, data=data)
if r.status_code == 200:
response = r.json()
token = response[ID_TOKEN]
refresh_token = response[REFRESH_TOKEN]
request.META["HTTP_AUTHORIZATION"] = "Bearer " + token
request.META["MODIFIED"] = "True"
kwargs['refresh_token'] = refresh_token
return view_func(request, *args, **kwargs)
else:
return Response({'action': "Get Token", 'message': "Invalid Auth Code"},
status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
logger.warning("Get Token: " + str(sys.exc_info()))
return Response({'action': "Get Token", 'message': str(e)},
status=status.HTTP_400_BAD_REQUEST)
return wrapper_func
return decorator
def precheck(required_data=None): def precheck(required_data=None):
if required_data is None: if required_data is None:
required_data = [] required_data = []
@ -84,7 +116,10 @@ def isAuthorized(allowed_users=None):
user.last_login_time = timezone.now() user.last_login_time = timezone.now()
user.save() user.save()
if len(set(user.user_type).intersection(set(allowed_users))) or allowed_users == '*': if len(set(user.user_type).intersection(set(allowed_users))) or allowed_users == '*':
return view_func(request, user.id, user.email, user.user_type, *args, **kwargs) if "MODIFIED" in headers:
return view_func(request, user.id, user.email, user.user_type, token_id, *args, **kwargs)
else:
return view_func(request, user.id, user.email, user.user_type, *args, **kwargs)
else: else:
raise PermissionError("Access Denied. You are not allowed to use this service") raise PermissionError("Access Denied. You are not allowed to use this service")
else: else:
@ -285,7 +320,7 @@ def opening_description_table_html(opening):
else: # if isinstance(opening, QueryDict): else: # if isinstance(opening, QueryDict):
details = opening details = opening
keys = list(details.keys()) keys = list(details.keys())
newdetails = {} newdetails = {"ID": opening.id}
for key in keys: for key in keys:
if isinstance(details[key], list): if isinstance(details[key], list):
details[key] = {"details": details[key], "type": ["list"]} details[key] = {"details": details[key], "type": ["list"]}

View File

@ -30,7 +30,7 @@ DEBUG = os.environ.get('DEBUG') == "True"
ALLOWED_HOSTS = ['cdc.iitdh.ac.in', 'localhost'] ALLOWED_HOSTS = ['cdc.iitdh.ac.in', 'localhost']
ADMINS = [('Gowtham Sai', '190010036@iitdh.ac.in'), ('Karthik Mv', '200010030@iitdh.ac.in')] ADMINS = [ ('Karthik Mv', '200010030@iitdh.ac.in')]
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
@ -47,7 +47,7 @@ INSTALLED_APPS = [
'background_task', 'background_task',
'simple_history', 'simple_history',
'import_export', 'import_export',
"django_extensions" 'django_extensions'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -0,0 +1,63 @@
from APIs.models import Placement, Student, PlacementApplication, User
from APIs.utils import sendEmail, PlacementApplicationConditions
from APIs.constants import *
from django.shortcuts import get_object_or_404
from django.utils import timezone
import time
import pytz
REPEAT_AFTER = 10 * 60
def send_reminder_mails():
placements = Placement.objects.all()
students = Student.objects.all()
for placement in placements.iterator():
print("Processing placement: ", placement)
# if placement is approved and email is verified
if not (placement.offer_accepted and placement.email_verified):
continue
# if placement is not expired
if placement.deadline_datetime < timezone.now():
continue
# send the reminder mail if the deadline is within 24 hours +- ReapetAfter
if timezone.now() - timezone.timedelta(
seconds=REPEAT_AFTER) <= placement.deadline_datetime - timezone.timedelta(days=1) < timezone.now() + \
timezone.timedelta(seconds=REPEAT_AFTER):
for student in students:
try:
# if Application not found then send email
if not PlacementApplication.objects.filter(placement=placement, student=student).exists():
if student.branch in placement.allowed_branch:
if student.degree == 'bTech' or placement.rs_eligible is True:
if PlacementApplicationConditions(student, placement)[0]:
student_user = get_object_or_404(User, id=student.id)
# change timezone to IST
deadline_datetime = placement.deadline_datetime.astimezone(pytz.timezone('Asia/Kolkata'))
data = {
"company_name": placement.company_name,
"opening_type": 'Placement',
"deadline": deadline_datetime.strftime("%A, %-d %B %Y, %-I:%M %p"),
"link": PLACEMENT_OPENING_URL.format(id=placement.id)
}
print("Sending mail to " + student_user.email, "placement id: ", placement.id)
sendEmail(student_user.email,
REMINDER_STUDENTS_OPENING_TEMPLATE_SUBJECT.format(
company_name=placement.company_name),
data, REMINDER_STUDENTS_OPENING_TEMPLATE)
except Exception as e:
print(e)
continue
def run():
while True:
print("Sleeping for", REPEAT_AFTER, "seconds")
time.sleep(REPEAT_AFTER)
print("Running send_reminder_mails()")
send_reminder_mails()

View File

@ -45,7 +45,7 @@
<h1 style="font-size:24px;margin:0 0 20px 0;font-family: 'Roboto', sans-serif; <h1 style="font-size:24px;margin:0 0 20px 0;font-family: 'Roboto', sans-serif;
">{{ opening_type }} Opportunity at {{ company_name }}</h1> ">{{ opening_type }} Opportunity at {{ company_name }}</h1>
<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family: 'Roboto', sans-serif;"> <p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family: 'Roboto', sans-serif;">
Gentle reminder for the same. Gentle reminder to fill out the application form.
Interested students can apply before <b>{{ deadline }}</b> in the <a Interested students can apply before <b>{{ deadline }}</b> in the <a
href="{{ link }}">CDC-webportal</a>. href="{{ link }}">CDC-webportal</a>.
</p> </p>

View File

@ -5,7 +5,8 @@ python# CDC - Backend
### Setup ### Setup
1. Download the Repository to your local machine <br> 1. Download the Repository to your local machine <br>
2. Create a Virtual Environment in the [CDC_Backend](./) folder with this command below <br> 2. Make Sure u have downloaded python from python.org or windows store.
3. Create a Virtual Environment in the [CDC_Backend](./) folder with this command below <br>
`python -m venv venv` `python -m venv venv`
3. Activate the environment with this command <br> 3. Activate the environment with this command <br>
`.\venv\Scripts\activate` (for WINDOWS) <br> `.\venv\Scripts\activate` (for WINDOWS) <br>
@ -14,6 +15,17 @@ python# CDC - Backend
`pip install -r requirements.txt ` `pip install -r requirements.txt `
5. Ensure that you have the PostgreSQL installed on your machine and is running on PORT **5432** <br> 5. Ensure that you have the PostgreSQL installed on your machine and is running on PORT **5432** <br>
6. Make sure to give the correct database credentials in [settings.py](./CDC_Backend/CDC_Backend/settings.py)(https://www.youtube.com/watch?v=bE9h6aAky4s&t=193s) 6. Make sure to give the correct database credentials in [settings.py](./CDC_Backend/CDC_Backend/settings.py)(https://www.youtube.com/watch?v=bE9h6aAky4s&t=193s)
7. Run these following commands below. (The same are there in setup.sh for linux users and setup.bat for windows users)
```cd CDC_Backend
python manage.py flush --no-input
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic --noinput
mkdir Storage
python manage.py makemigrations APIs
```
### Running the Application ### Running the Application
@ -28,13 +40,20 @@ python# CDC - Backend
1. You can access the admin panel by running the server and opening <http://localhost:8000/admin> 1. You can access the admin panel by running the server and opening <http://localhost:8000/admin>
2. Run `python manage.py createsuperuser` to create a user to access the admin panel. 2. Run `python manage.py createsuperuser` to create a user to access the admin panel.
3. Set up the Username and Password 3. if there is an error due to time then sync your machine time .
4. You can log in and change the database values anytime. 4. Set up the Username and Password
5. You can log in and change the database values anytime.
6. Create your id as insitute Roll No for both admin and student .
7. if you are still getting an error ,open inspect and see in network
And then recognize it
8.Check the client link in dev.env in backend and .env in frontend is the same
# Error # Error
1.make sure that your machine time and google time are same ,if not go to setting of date and time and sync this 1.make sure that your machine time and google time are same ,if not go to setting of date and time and sync this
2.make sure u have used same id for both student and Admin that is your iitfh roll_no 2.make sure u have used same id for both student and Admin that is your iitfh roll_no
3. same client link in .env of frontend or constants.py of bakcend 3. same client link in .env of frontend or constants.py of bakcend
### Deploying ### Deploying
1. Add the hosted domain name in `ALLOWED_HOSTS` in [settings.py](./CDC_Backend/CDC_Backend/settings.py) 1. Add the hosted domain name in `ALLOWED_HOSTS` in [settings.py](./CDC_Backend/CDC_Backend/settings.py)

View File

@ -1,6 +1,6 @@
typical conf file for pg_hba.conf for dev work. typical conf file for pg_hba.conf for dev work.
```
# TYPE DATABASE USER ADDRESS METHOD # TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only # "local" is for Unix domain socket connections only
@ -13,4 +13,5 @@ host all all ::1/128 md5
# replication privilege. # replication privilege.
local replication all peer local replication all peer
host replication all 127.0.0.1/32 ident host replication all 127.0.0.1/32 ident
host replication all ::1/128 ident host replication all ::1/128 ident
```

View File

@ -14,6 +14,7 @@ django-background-tasks==1.2.5
django-compat==1.0.15 django-compat==1.0.15
django-cors-headers==3.11.0 django-cors-headers==3.11.0
django-db-logger==0.1.12 django-db-logger==0.1.12
django-extensions==3.2.1
django-import-export==2.8.0 django-import-export==2.8.0
django-simple-history==3.1.1 django-simple-history==3.1.1
djangorestframework==3.13.1 djangorestframework==3.13.1

15
setup.bat Normal file
View File

@ -0,0 +1,15 @@
start /wait python -m venv venv && venv\Scripts\activate && pip install -r requirements.txt &^
echo Environment Setup Complete &^
timeout 3 > NUL &^
echo enter password for user postgres &^
createdb -h localhost -p 5432 -U postgres cdc &^
cd "CDC_Backend" &^
python manage.py flush --no-input &^
python manage.py makemigrations &^
python manage.py migrate &^
echo Migrations complete &^
cd .. &^
start .\superuser.bat &^
echo done successfully

View File

@ -20,3 +20,11 @@ else
echo "${DIR} Directory Created" echo "${DIR} Directory Created"
fi fi
echo Do you want ceate credentials for super user (Y/N) ?
read create
create=${create^^}
if [ "$create" == "Y" ]; then
### Take action if user want to create ###
python3 manage.py createsuperuser
fi

12
superuser.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
set /p create="do you want to create supruser ? (Y/N) "
cd "CDC_Backend" &^
if %create% equ Y ( python manage.py createsuperuser )
if %create% equ y ( python manage.py createsuperuser )
python manage.py collectstatic --noinput
if exist Storage (echo Storage Directory already exists) else ( echo Creating Storage Directory... & mkdir Storage & echo Storage Directory Created)
timeout 3 > NUL
pause