import datetime import json import logging import os import random import re import string import sys import traceback from os import path, remove import background_task import jwt import pdfkit import requests as rq from django.conf import settings from django.core.mail import EmailMultiAlternatives from django.forms.models import model_to_dict from django.http import Http404 from django.shortcuts import get_object_or_404 from django.template.loader import render_to_string from django.utils.html import strip_tags from google.auth.transport import requests from google.oauth2 import id_token from rest_framework import status from rest_framework.response import Response from .constants import * from .models import User, PrePlacementOffer, PlacementApplication, Placement logger = logging.getLogger('db') def precheck(required_data=None): if required_data is None: required_data = [] def decorator(view_func): def wrapper_func(request, *args, **kwargs): try: request_data = None if request.method == 'GET': request_data = request.GET elif request.method == 'POST': request_data = request.data if not len(request_data): request_data = request.POST if len(request_data): for i in required_data: if i not in request_data: return Response({'action': "Pre check", 'message': str(i) + " Not Found"}, status=status.HTTP_400_BAD_REQUEST) else: return Response({'action': "Pre check", 'message': "Message Data not Found"}, status=status.HTTP_400_BAD_REQUEST) return view_func(request, *args, **kwargs) except: return Response({'action': "Pre check", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) return wrapper_func return decorator def isAuthorized(allowed_users=None): if allowed_users is None: allowed_users = [] def decorator(view_func): def wrapper_func(request, *args, **kwargs): try: headers = request.META if 'HTTP_AUTHORIZATION' in headers: token_id = headers['HTTP_AUTHORIZATION'][7:] idinfo = id_token.verify_oauth2_token(token_id, requests.Request(), CLIENT_ID) email = idinfo[EMAIL] print(email) user = get_object_or_404(User, email=email) if user: user.last_login_time = datetime.datetime.now() user.save() 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) else: raise PermissionError("Access Denied. You are not allowed to use this service") else: raise PermissionError("Authorization Header Not Found") except PermissionError: return Response({'action': "Is Authorized?", 'message': 'Access Denied'}, status=status.HTTP_401_UNAUTHORIZED) except Http404: return Response({'action': "Is Authorized?", 'message': "User Not Found. Contact CDC for more details"}, status=status.HTTP_404_NOT_FOUND) except ValueError as e: logger.error("Problem with Google Oauth2.0 " + str(e)) return Response({'action': "Is Authorized?", 'message': 'Problem with Google Sign In'}, status=status.HTTP_401_UNAUTHORIZED) except: logger.warning("Is Authorized? " + str(sys.exc_info())) return Response( {'action': "Is Authorized?", 'message': "Something went wrong. Contact CDC for more details"}, status=status.HTTP_400_BAD_REQUEST) return wrapper_func return decorator def generateRandomString(): try: N = 15 res = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=N)) return res except: return False def saveFile(file, location): prefix = generateRandomString() file_name = prefix + "_" + file.name file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name) if not path.isdir(location): os.makedirs(location) destination_path = location + str(file_name) if path.exists(destination_path): remove(destination_path) with open(destination_path, 'wb+') as destination: for chunk in file.chunks(): destination.write(chunk) return file_name @background_task.background(schedule=10) def sendEmail(email_to, subject, data, template, attachment_jnf_respone=None): try: if not isinstance(data, dict): data = json.loads(data) html_content = render_to_string(template, data) # render with dynamic value text_content = strip_tags(html_content) email_from = settings.EMAIL_HOST_USER recipient_list = [str(email_to), ] msg = EmailMultiAlternatives(subject, text_content, email_from, recipient_list) msg.attach_alternative(html_content, "text/html") if attachment_jnf_respone: logger.info(attachment_jnf_respone) pdf = pdfkit.from_string(attachment_jnf_respone['html'], False, options={"--enable-local-file-access": "", '--dpi': '96'}) msg.attach(attachment_jnf_respone['name'], pdf, 'application/pdf') msg.send() return True except: logger.error("Send Email: " + str(sys.exc_info())) print(str(sys.exc_info()[1])) return False def PlacementApplicationConditions(student, placement): try: 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) # find lenght of PPO print(PPO) print(len(PPO), "ere") 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 placement.tier == 'psu': return True, "Conditions Satisfied" for i in selected_companies: print(int(i.placement.tier) < int(placement.tier), int(i.placement.tier), int(placement.tier)) if int(i.placement.tier) < int(placement.tier): return False, "Can't apply for this tier" return True, "Conditions Satisfied" except PermissionError as e: return False, e except: print(sys.exc_info()) print(traceback.format_exc()) logger.warning("Utils - PlacementApplicationConditions: " + str(sys.exc_info())) return False, "_" def getTier(compensation_gross, is_psu=False): try: if is_psu: return True, 'psu' if compensation_gross < 0: raise ValueError("Negative Compensation") elif compensation_gross < 600000: # Tier 7 If less than 600,000 return True, "7" # Tier 6 If less than 800,000 and greater than or equal to 600,000 elif compensation_gross < 800000: return True, "6" # Tier 5 If less than 1,000,000 and greater than or equal to 800,000 elif compensation_gross < 1000000: return True, "5" # Tier 4 If less than 1,200,000 and greater than or equal to 1,000,000 elif compensation_gross < 1200000: return True, "4" # Tier 3 If less than 1,500,000 and greater than or equal to 1,200,000 elif compensation_gross < 1500000: return True, "3" # Tier 2 If less than 1,800,000 and greater than or equal to 1,500,000 elif compensation_gross < 1800000: return True, "2" # Tier 1 If greater than or equal to 1,800,000 elif compensation_gross >= 1800000: return True, "1" else: raise ValueError("Invalid Compensation") except ValueError as e: logger.warning("Utils - getTier: " + str(sys.exc_info())) return False, e except: 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, "_" def verify_recaptcha(request): try: print(settings.RECAPTCHA_SECRET_KEY) data = { 'secret': settings.RECAPTCHA_SECRET_KEY, 'response': request } print(data) r = rq.post('https://www.google.com/recaptcha/api/siteverify', data=data) result = r.json() # logger.info("Recaptcha Response: " + str(result)+"request: "+str(data)) print(result, "Result") return result['success'] except: # get exception line number print(sys.exc_info()) print(traceback.format_exc()) logger.warning("Utils - verify_recaptcha: " + str(sys.exc_info())) return False, "_" def opening_description_table_html(opening): details = model_to_dict(opening, fields=[field.name for field in Placement._meta.fields], exclude=['id', 'is_company_details_pdf', 'offer_accepted', 'is_description_pdf', 'is_compensation_details_pdf', 'is_selection_procedure_details_pdf', 'email_verified']) keys = list(details.keys()) newdetails = {} for key in keys: if isinstance(details[key], list): details[key] = {"details": details[key], "type": ["list"]} if key in ['website', 'company_details_pdf_names', 'description_pdf_names', 'compensation_details_pdf_names', 'selection_procedure_pdf_names']: if key == 'website': details[key] = {"details": details[key], "type": ["link"]} else: details[key] = {"details": details[key]["details"], "type": ["list", "link"], "link": PDF_FILES_SERVING_ENDPOINT + opening.id + "/"} new_key = key.replace('_', ' ') if key.endswith(' names'): new_key = key[:-6] new_key = new_key.capitalize() newdetails[new_key] = details[key] imagepath = os.path.abspath('./templates/image.png') print(imagepath) data = { "data": newdetails, "imgpath": imagepath } return render_to_string(COMPANY_JNF_RESPONSE_TEMPLATE, data)