From 419eaa40ac17be979f23288b34a69ee701c04f68 Mon Sep 17 00:00:00 2001 From: Abhishek28112002 <72252789+Abhishek28112002@users.noreply.github.com> Date: Thu, 2 Jun 2022 15:45:22 +0530 Subject: [PATCH 1/9] Update README.md --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 83ac1d8..21b39b1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ python# CDC - Backend ### Setup 1. Download the Repository to your local machine
-2. Create a Virtual Environment in the [CDC_Backend](./) folder with this command below
+2. Make Sour u have downloaded python from python.org +3. Create a Virtual Environment in the [CDC_Backend](./) folder with this command below
`python -m venv venv` 3. Activate the environment with this command
`.\venv\Scripts\activate` @@ -13,6 +14,15 @@ 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**
6. Make sure to give the correct database credentials in [settings.py](./CDC_Backend/CDC_Backend/settings.py) +7. Run these following commands .. +8. 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 @@ -26,8 +36,13 @@ python# CDC - Backend 1. You can access the admin panel by running the server and opening 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 u 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 ### Deploying From 36a2f8c200fd912df5e5eb5d984d40daa52b4312 Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Thu, 3 Nov 2022 16:46:56 +0530 Subject: [PATCH 2/9] Adding an api call and service for Contributors page (#148) --- CDC_Backend/APIs/models.py | 13 ++++ CDC_Backend/APIs/serializers.py | 4 ++ CDC_Backend/APIs/studentUrls.py | 1 + CDC_Backend/APIs/studentViews.py | 16 +++++ CDC_Backend/CDC_Backend/settings.py | 1 + CDC_Backend/scripts/__init__.py | 0 CDC_Backend/scripts/get_contributor_stats.py | 70 ++++++++++++++++++++ 7 files changed, 105 insertions(+) create mode 100644 CDC_Backend/scripts/__init__.py create mode 100644 CDC_Backend/scripts/get_contributor_stats.py diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index 9b15724..77d8c6a 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -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 \ No newline at end of file diff --git a/CDC_Backend/APIs/serializers.py b/CDC_Backend/APIs/serializers.py index 1447d6d..ad7d9f7 100644 --- a/CDC_Backend/APIs/serializers.py +++ b/CDC_Backend/APIs/serializers.py @@ -185,3 +185,7 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer): class Meta: model = PlacementApplication exclude = ['placement', 'resume'] + +class ContributorSerializer(serializers.ModelSerializer): + class Meta: + model = Contributor \ No newline at end of file diff --git a/CDC_Backend/APIs/studentUrls.py b/CDC_Backend/APIs/studentUrls.py index 45b3619..8a1acce 100644 --- a/CDC_Backend/APIs/studentUrls.py +++ b/CDC_Backend/APIs/studentUrls.py @@ -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"), ] diff --git a/CDC_Backend/APIs/studentViews.py b/CDC_Backend/APIs/studentViews.py index 45993a5..c68d846 100644 --- a/CDC_Backend/APIs/studentViews.py +++ b/CDC_Backend/APIs/studentViews.py @@ -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) \ No newline at end of file diff --git a/CDC_Backend/CDC_Backend/settings.py b/CDC_Backend/CDC_Backend/settings.py index c5667cf..077e389 100644 --- a/CDC_Backend/CDC_Backend/settings.py +++ b/CDC_Backend/CDC_Backend/settings.py @@ -46,6 +46,7 @@ INSTALLED_APPS = [ 'background_task', 'simple_history', 'import_export', + "django_extensions" ] MIDDLEWARE = [ diff --git a/CDC_Backend/scripts/__init__.py b/CDC_Backend/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/CDC_Backend/scripts/get_contributor_stats.py b/CDC_Backend/scripts/get_contributor_stats.py new file mode 100644 index 0000000..ef98c88 --- /dev/null +++ b/CDC_Backend/scripts/get_contributor_stats.py @@ -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() \ No newline at end of file From 3f526a685013eee22688d30f35c773b666c0ed6e Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Tue, 8 Nov 2022 21:57:51 +0530 Subject: [PATCH 3/9] Adding Stats API (#147) --- CDC_Backend/APIs/adminUrls.py | 1 + CDC_Backend/APIs/adminViews.py | 202 +++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) diff --git a/CDC_Backend/APIs/adminUrls.py b/CDC_Backend/APIs/adminUrls.py index 587c1bb..da8acd6 100644 --- a/CDC_Backend/APIs/adminUrls.py +++ b/CDC_Backend/APIs/adminUrls.py @@ -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"), ] diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index e4f0cc2..9b07f80 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -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() + 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) From d918735bf815972d5562f9bc61771f80ccbef004 Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Tue, 6 Dec 2022 16:16:56 +0530 Subject: [PATCH 4/9] Minor changes and PPO-PSU check --- CDC_Backend/APIs/utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index 2f5c6fc..be57175 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -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: From f41a0e85e9b6e7877dd9369e4d6f04319d7b6eac Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Tue, 6 Dec 2022 16:18:23 +0530 Subject: [PATCH 5/9] Adding Email Notifications to ADMINS for Warning Logs or Above --- CDC_Backend/CDC_Backend/settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CDC_Backend/CDC_Backend/settings.py b/CDC_Backend/CDC_Backend/settings.py index 077e389..2447ee0 100644 --- a/CDC_Backend/CDC_Backend/settings.py +++ b/CDC_Backend/CDC_Backend/settings.py @@ -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 = [ @@ -185,14 +186,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' } } From cece6155cdfd6b089761bd24eda801369fbfcec6 Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Tue, 6 Dec 2022 16:22:27 +0530 Subject: [PATCH 6/9] Sorting students by roll No by default (#150) --- CDC_Backend/APIs/adminViews.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index 9b07f80..e935e8d 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -511,7 +511,7 @@ def getStats(request, id, email, user_type): - students = Student.objects.all() + students = Student.objects.all().order_by("roll_no") for student in students.iterator(): applications = PlacementApplication.objects.filter(student=student, selected=True) From dbc875eabfd23b3f94ce468cbb7a7753f4baf90c Mon Sep 17 00:00:00 2001 From: Gowtham Sai <66207607+gowtham3105@users.noreply.github.com> Date: Fri, 30 Dec 2022 17:30:02 +0530 Subject: [PATCH 7/9] minor fix to contributors api --- CDC_Backend/APIs/serializers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CDC_Backend/APIs/serializers.py b/CDC_Backend/APIs/serializers.py index ad7d9f7..bc8cbaa 100644 --- a/CDC_Backend/APIs/serializers.py +++ b/CDC_Backend/APIs/serializers.py @@ -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: @@ -186,6 +187,8 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer): model = PlacementApplication exclude = ['placement', 'resume'] + class ContributorSerializer(serializers.ModelSerializer): class Meta: - model = Contributor \ No newline at end of file + model = Contributor + fields = '__all__' From b94d63febe3e4f5ddcb14a666e2b21744d962cb6 Mon Sep 17 00:00:00 2001 From: karthik mv Date: Tue, 2 May 2023 00:49:01 +0530 Subject: [PATCH 8/9] Update postgres.md --- doc/setup/postgres.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/setup/postgres.md b/doc/setup/postgres.md index d3dba5e..8941fa6 100644 --- a/doc/setup/postgres.md +++ b/doc/setup/postgres.md @@ -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 \ No newline at end of file +host replication all ::1/128 ident +``` From adc33a2430eca9b877b80563318b400b68d85f92 Mon Sep 17 00:00:00 2001 From: karthikmurakonda Date: Tue, 30 May 2023 15:00:02 +0530 Subject: [PATCH 9/9] make corrections to pr --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 21b39b1..5c37318 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ python# CDC - Backend ### Setup 1. Download the Repository to your local machine
-2. Make Sour u have downloaded python from python.org +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
`python -m venv venv` 3. Activate the environment with this command
@@ -14,14 +14,15 @@ 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**
6. Make sure to give the correct database credentials in [settings.py](./CDC_Backend/CDC_Backend/settings.py) -7. Run these following commands .. -8. cd CDC_Backend +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 @@ -40,7 +41,7 @@ python manage.py makemigrations APIs 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 u are still getting an error ,open inspect and see in network +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