Merge branch 'main' into gowtham/send-reminder-mails
This commit is contained in:
commit
65fc6face4
|
@ -15,4 +15,5 @@ urlpatterns = [
|
|||
path('generateCSV/', adminViews.generateCSV, name="Generate CSV"),
|
||||
path('addPPO/', adminViews.addPPO, name="Add PPO"),
|
||||
path('getStudentApplication/', adminViews.getStudentApplication, name="Get student application"),
|
||||
path('getStats/', adminViews.getStats, name="Get Stats"),
|
||||
]
|
||||
|
|
|
@ -429,3 +429,205 @@ def getStudentApplication(request, id, email, user_type):
|
|||
logger.warning("Get Student Application: " + str(sys.exc_info()))
|
||||
return Response({'action': "Get Student Application", 'message': "Something Went Wrong"},
|
||||
status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@api_view(['GET'])
|
||||
@isAuthorized(allowed_users=[ADMIN])
|
||||
def getStats(request, id, email, user_type):
|
||||
try:
|
||||
stats = []
|
||||
placement_ids = {}
|
||||
|
||||
tier_count = {
|
||||
"CSE": {
|
||||
"1":0,
|
||||
"2":0,
|
||||
"3":0,
|
||||
"4":0,
|
||||
"5":0,
|
||||
"6":0,
|
||||
"7":0,
|
||||
"psu":0,
|
||||
},
|
||||
"EE": {
|
||||
"1":0,
|
||||
"2":0,
|
||||
"3":0,
|
||||
"4":0,
|
||||
"5":0,
|
||||
"6":0,
|
||||
"7":0,
|
||||
"psu":0,
|
||||
},
|
||||
"MMAE": {
|
||||
"1":0,
|
||||
"2":0,
|
||||
"3":0,
|
||||
"4":0,
|
||||
"5":0,
|
||||
"6":0,
|
||||
"7":0,
|
||||
"psu":0,
|
||||
|
||||
},
|
||||
"Total": {
|
||||
"1":0,
|
||||
"2":0,
|
||||
"3":0,
|
||||
"4":0,
|
||||
"5":0,
|
||||
"6":0,
|
||||
"7":0,
|
||||
"psu":0,
|
||||
},
|
||||
}
|
||||
number_of_students_placed = {
|
||||
"CSE": 0,
|
||||
"EE": 0,
|
||||
"MMAE": 0,
|
||||
"Total": 0,
|
||||
}
|
||||
number_of_students_with_multiple_offers = 0
|
||||
number_of_students_with_no_offers = {
|
||||
"CSE": 0,
|
||||
"EE": 0,
|
||||
"MMAE": 0,
|
||||
"Total": 0,
|
||||
}
|
||||
max_CTC = {
|
||||
"CSE": 0,
|
||||
"EE": 0,
|
||||
"MMAE": 0
|
||||
}
|
||||
average_CTC = {
|
||||
"CSE": 0,
|
||||
"EE": 0,
|
||||
"MMAE": 0
|
||||
}
|
||||
count = {
|
||||
"CSE": 0,
|
||||
"EE": 0,
|
||||
"MMAE": 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
students = Student.objects.all().order_by("roll_no")
|
||||
for student in students.iterator():
|
||||
|
||||
applications = PlacementApplication.objects.filter(student=student, selected=True)
|
||||
ppos = PrePlacementOffer.objects.filter(student=student, accepted=True)
|
||||
|
||||
first_offer_data = None
|
||||
|
||||
second_offer_data = None
|
||||
|
||||
# get the first and second offer
|
||||
offers = []
|
||||
offers.extend(applications)
|
||||
offers.extend(ppos)
|
||||
|
||||
if len(offers) == 0:
|
||||
number_of_students_with_no_offers[student.branch] += 1
|
||||
number_of_students_with_no_offers["Total"] += 1
|
||||
else:
|
||||
number_of_students_placed[student.branch] += 1
|
||||
number_of_students_placed["Total"] += 1
|
||||
if len(offers) > 1:
|
||||
number_of_students_with_multiple_offers += 1
|
||||
|
||||
|
||||
|
||||
for offer in offers:
|
||||
if type(offer) == PrePlacementOffer:
|
||||
if first_offer_data is None:
|
||||
first_offer_data = {
|
||||
"id": offer.id,
|
||||
"company": offer.company,
|
||||
"compensation": offer.compensation,
|
||||
"tier": offer.tier,
|
||||
"type": "PPO",
|
||||
}
|
||||
elif second_offer_data is None:
|
||||
second_offer_data = {
|
||||
"id": offer.id,
|
||||
"company": offer.company,
|
||||
"compensation": offer.compensation,
|
||||
"tier": offer.tier,
|
||||
"type": "PPO",
|
||||
}
|
||||
elif type(offer) == PlacementApplication:
|
||||
if first_offer_data is None:
|
||||
first_offer_data = {
|
||||
"id": offer.placement.id,
|
||||
"company": offer.placement.company_name,
|
||||
"compensation": offer.placement.compensation_CTC,
|
||||
"tier": offer.placement.tier,
|
||||
"type": "Placement",
|
||||
}
|
||||
elif second_offer_data is None:
|
||||
second_offer_data = {
|
||||
"id": offer.placement.id,
|
||||
"company": offer.placement.company_name,
|
||||
"compensation": offer.placement.compensation_CTC,
|
||||
"tier": offer.placement.tier,
|
||||
"type": "Placement",
|
||||
}
|
||||
|
||||
data = {
|
||||
"id": student.id,
|
||||
"name": student.name,
|
||||
"roll_no": student.roll_no,
|
||||
"batch": student.batch,
|
||||
"branch": student.branch,
|
||||
"cpi": student.cpi,
|
||||
"first_offer": first_offer_data['company'] if first_offer_data is not None else None,
|
||||
"first_offer_tier": first_offer_data['tier'] if first_offer_data is not None else None,
|
||||
"first_offer_compensation": first_offer_data['compensation'] if first_offer_data is not None else None,
|
||||
|
||||
"second_offer": second_offer_data['company'] if second_offer_data is not None else None,
|
||||
"second_offer_tier": second_offer_data['tier'] if second_offer_data is not None else None,
|
||||
"second_offer_compensation": second_offer_data['compensation'] if second_offer_data is not None else None,
|
||||
}
|
||||
if first_offer_data is not None:
|
||||
tier_count[student.branch][first_offer_data['tier']] += 1
|
||||
tier_count['Total'][first_offer_data['tier']] += 1
|
||||
max_CTC[student.branch] = max(max_CTC[student.branch], first_offer_data['compensation'])
|
||||
average_CTC[student.branch] += first_offer_data['compensation']
|
||||
count[student.branch] += 1
|
||||
|
||||
if first_offer_data['type'] == "Placement":
|
||||
placement_ids[first_offer_data['company']] = first_offer_data['id']
|
||||
|
||||
if second_offer_data is not None:
|
||||
tier_count[student.branch][second_offer_data['tier']] += 1
|
||||
tier_count['Total'][second_offer_data['tier']] += 1
|
||||
max_CTC[student.branch] = max(max_CTC[student.branch], second_offer_data['compensation'])
|
||||
average_CTC[student.branch] += second_offer_data['compensation']
|
||||
count[student.branch] += 1
|
||||
|
||||
if second_offer_data['type'] == "Placement":
|
||||
placement_ids[second_offer_data['company']] = second_offer_data['id']
|
||||
|
||||
stats.append(data)
|
||||
|
||||
for branch in average_CTC:
|
||||
if count[branch] > 0:
|
||||
average_CTC[branch] /= count[branch]
|
||||
# round off to 2 decimal places
|
||||
average_CTC[branch] = round(average_CTC[branch], 2)
|
||||
else:
|
||||
average_CTC[branch] = 0
|
||||
return Response({'action': "Get Stats", 'message': "Stats fetched", 'stats': stats, 'placement_ids': placement_ids,
|
||||
"tier_count": {br: tier_count[br].values() for br in tier_count},
|
||||
"number_of_students_placed": number_of_students_placed,
|
||||
"number_of_students_with_multiple_offers": number_of_students_with_multiple_offers,
|
||||
"number_of_students_with_no_offers": number_of_students_with_no_offers,
|
||||
"max_CTC": max_CTC,
|
||||
"average_CTC": average_CTC,
|
||||
},
|
||||
status=status.HTTP_200_OK)
|
||||
except:
|
||||
logger.warning("Get Stats: " + str(sys.exc_info()))
|
||||
print(sys.exc_info())
|
||||
return Response({'action': "Get Stats", 'message': "Something Went Wrong"},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
|
@ -276,3 +276,16 @@ class PrePlacementOffer(models.Model):
|
|||
self.changed_by = value
|
||||
else:
|
||||
self.changed_by = None
|
||||
|
||||
|
||||
class Contributor(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, blank=False, default="")
|
||||
email = models.EmailField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, blank=False, default="", unique=True)
|
||||
github_id = models.CharField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, blank=False, default="", unique=True)
|
||||
linkedin = models.CharField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, unique=True, null=True)
|
||||
commits = models.IntegerField(blank=False, default=0)
|
||||
image = models.CharField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, blank=False, default="", null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
|
@ -162,7 +162,8 @@ class PlacementApplicationSerializer(serializers.ModelSerializer):
|
|||
return data
|
||||
|
||||
def get_resume_link(self, obj):
|
||||
ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(str(obj.student.roll_no) + "/" + obj.resume), 'name': obj.resume}
|
||||
ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(str(obj.student.roll_no) + "/" + obj.resume),
|
||||
'name': obj.resume}
|
||||
return ele
|
||||
|
||||
class Meta:
|
||||
|
@ -185,3 +186,9 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = PlacementApplication
|
||||
exclude = ['placement', 'resume']
|
||||
|
||||
|
||||
class ContributorSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Contributor
|
||||
fields = '__all__'
|
||||
|
|
|
@ -10,4 +10,5 @@ urlpatterns = [
|
|||
path("deleteResume/", studentViews.deleteResume, name="Upload Resume"),
|
||||
path("submitApplication/", studentViews.submitApplication, name="Submit Application"),
|
||||
path("deleteApplication/", studentViews.deleteApplication, name="Delete Application"),
|
||||
path("getContributorStats/", studentViews.getContributorStats, name="Get Contributor Stats"),
|
||||
]
|
||||
|
|
|
@ -230,4 +230,20 @@ def deleteApplication(request, id, email, user_type):
|
|||
logger.warning("Delete Application: " + str(sys.exc_info()))
|
||||
|
||||
return Response({'action': "Delete Application", 'message': "Something Went Wrong"},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@isAuthorized(allowed_users='*')
|
||||
def getContributorStats(request, id, email, user_type):
|
||||
try:
|
||||
contributors = Contributor.objects.all()
|
||||
serialized_data = ContributorSerializer(contributors, many=True).data
|
||||
return Response({'action': "Get Contributor Stats", 'message': "Contributor Stats Fetched",
|
||||
'data': serialized_data},
|
||||
status=status.HTTP_200_OK)
|
||||
except:
|
||||
logger.warning("Get Contributor Stats: " + str(sys.exc_info()))
|
||||
|
||||
return Response({'action': "Get Contributor Stats", 'message': "Something Went Wrong"},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
|
@ -172,12 +172,17 @@ def PlacementApplicationConditions(student, placement):
|
|||
selected_companies = PlacementApplication.objects.filter(student=student, selected=True)
|
||||
selected_companies_PSU = [i for i in selected_companies if i.placement.tier == 'psu']
|
||||
PPO = PrePlacementOffer.objects.filter(student=student, accepted=True)
|
||||
PPO_PSU = [i for i in PPO if i.tier == 'psu']
|
||||
# find length of PPO
|
||||
if len(selected_companies) + len(PPO) >= MAX_OFFERS_PER_STUDENT:
|
||||
raise PermissionError("Max Applications Reached for the Season")
|
||||
|
||||
if len(selected_companies_PSU) > 0:
|
||||
raise PermissionError('Selected for PSU Can\'t apply anymore')
|
||||
|
||||
if len(PPO_PSU) > 0:
|
||||
raise PermissionError('Selected for PSU Can\'t apply anymore')
|
||||
|
||||
if placement.tier == 'psu':
|
||||
return True, "Conditions Satisfied"
|
||||
|
||||
|
@ -186,7 +191,7 @@ def PlacementApplicationConditions(student, placement):
|
|||
return False, "Can't apply for this tier"
|
||||
|
||||
for i in PPO:
|
||||
if int(i.placement.tier) < int(placement.tier):
|
||||
if int(i.tier) < int(placement.tier):
|
||||
return False, "Can't apply for this tier"
|
||||
|
||||
if student.degree != 'bTech' and not placement.rs_eligible:
|
||||
|
|
|
@ -30,6 +30,7 @@ DEBUG = os.environ.get('DEBUG') == "True"
|
|||
|
||||
ALLOWED_HOSTS = ['cdc.iitdh.ac.in', 'localhost']
|
||||
|
||||
ADMINS = [('Gowtham Sai', '190010036@iitdh.ac.in'), ('Karthik Mv', '200010030@iitdh.ac.in')]
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
@ -47,6 +48,8 @@ INSTALLED_APPS = [
|
|||
'simple_history',
|
||||
'import_export',
|
||||
'django_extensions',
|
||||
"django_extensions"
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -185,14 +188,13 @@ LOGGING = {
|
|||
'class': 'django_db_logger.db_log_handler.DatabaseLogHandler'
|
||||
},
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'level': 'WARNING',
|
||||
'class': 'django.utils.log.AdminEmailHandler',
|
||||
'include_html': True,
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'db': {
|
||||
'handlers': ['db_log'],
|
||||
'handlers': ['db_log', 'mail_admins'],
|
||||
'level': 'DEBUG'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
from APIs.models import Contributor
|
||||
from django.shortcuts import get_object_or_404
|
||||
import time
|
||||
from dotenv import load_dotenv
|
||||
import requests
|
||||
import os
|
||||
load_dotenv("../dev.env")
|
||||
|
||||
owner = 'CDC-IITDH'
|
||||
access_token = os.environ.get("GITHUB_ACCESS_TOKEN")
|
||||
headers = {'Authorization': "Token " + access_token}
|
||||
maxRetires = 10
|
||||
REPEAT_AFTER = 60 * 15 # 15 minutes
|
||||
|
||||
def getStats():
|
||||
try:
|
||||
stats = {}
|
||||
repos = ['cdc-placement-website-backend', 'cdc-placement-website-frontend']
|
||||
for i in repos:
|
||||
try:
|
||||
repo_name = i
|
||||
print(repo_name)
|
||||
url = f"https://api.github.com/repos/{owner}/{repo_name}/stats/contributors"
|
||||
retry = 0
|
||||
contributors = []
|
||||
while True:
|
||||
if retry > maxRetires:
|
||||
break
|
||||
req = requests.get(url, headers=headers)
|
||||
contributors = req.json()
|
||||
if req.status_code != 200:
|
||||
print("ERROR:", req.json())
|
||||
retry += 1
|
||||
elif len(contributors):
|
||||
break
|
||||
retry += 1
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
for contributor in contributors:
|
||||
if contributor['author']['login'] not in stats:
|
||||
stats[contributor['author']['login']] = 0
|
||||
stats[contributor['author']['login']] += contributor['total']
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
for i in stats:
|
||||
try:
|
||||
contributor = get_object_or_404(Contributor, github_id=i)
|
||||
contributor.commits = stats[i]
|
||||
contributor.save()
|
||||
except:
|
||||
pass
|
||||
|
||||
stats = sorted(stats.items(), key=lambda x: x[1], reverse=True)
|
||||
for i in stats:
|
||||
print(i)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return stats
|
||||
|
||||
|
||||
def run():
|
||||
while True:
|
||||
getStats()
|
||||
print("Sleeping for", REPEAT_AFTER, "seconds")
|
||||
time.sleep(REPEAT_AFTER)
|
||||
print("Running send_reminder_mails()")
|
||||
|
||||
run()
|
25
README.md
25
README.md
|
@ -5,7 +5,8 @@ python# CDC - Backend
|
|||
### Setup
|
||||
|
||||
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`
|
||||
3. Activate the environment with this command <br>
|
||||
`.\venv\Scripts\activate` (for WINDOWS) <br>
|
||||
|
@ -14,6 +15,17 @@ python# CDC - Backend
|
|||
`pip install -r requirements.txt `
|
||||
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)
|
||||
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
|
||||
|
||||
|
@ -28,13 +40,20 @@ python# CDC - Backend
|
|||
|
||||
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.
|
||||
3. Set up the Username and Password
|
||||
4. You can log in and change the database values anytime.
|
||||
3. if there is an error due to time then sync your machine time .
|
||||
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
|
||||
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
|
||||
3. same client link in .env of frontend or constants.py of bakcend
|
||||
|
||||
### Deploying
|
||||
|
||||
1. Add the hosted domain name in `ALLOWED_HOSTS` in [settings.py](./CDC_Backend/CDC_Backend/settings.py)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
typical conf file for pg_hba.conf for dev work.
|
||||
|
||||
|
||||
```
|
||||
# TYPE DATABASE USER ADDRESS METHOD
|
||||
|
||||
# "local" is for Unix domain socket connections only
|
||||
|
@ -13,4 +13,5 @@ host all all ::1/128 md5
|
|||
# replication privilege.
|
||||
local replication all peer
|
||||
host replication all 127.0.0.1/32 ident
|
||||
host replication all ::1/128 ident
|
||||
host replication all ::1/128 ident
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue