diff --git a/mftp/company.py b/mftp/company.py
index 84ecabf..b7ee855 100644
--- a/mftp/company.py
+++ b/mftp/company.py
@@ -30,6 +30,9 @@ def filter(companies, filter):
for company in companies:
if filter_func(company):
filtered.append(company)
+ logging.info(
+ f" {company['Name']} | {company['Role']} | {company['CTC']} | {company['End_Date']} | {company['Interview_Date']}"
+ )
return filtered
@@ -102,11 +105,17 @@ def get_new_and_modified_companies(fetched, stored, unique_key="Job_Description"
if key not in stored_dict:
# New entry
new_entries.append(fetched_entry)
+ logging.info(
+ f" [NEW COMPANY]: {fetched_entry['Name']} | {fetched_entry['Role']} | {fetched_entry['CTC']} | {fetched_entry['End_Date']} | {fetched_entry['Interview_Date']}"
+ )
else:
# Compare the values of the fetched entry with the stored entry
stored_entry = stored_dict[key]
if any(fetched_entry[k] != stored_entry.get(k) for k in fetched_entry):
updated_entries.append(fetched_entry)
+ logging.info(
+ f" [MODIFIED COMPANY]: {fetched_entry['Name']} | {fetched_entry['Role']} | {fetched_entry['CTC']} | {fetched_entry['End_Date']} | {fetched_entry['Interview_Date']}"
+ )
return new_entries, updated_entries
diff --git a/mftp/env.example.py b/mftp/env.example.py
index e50aa14..5b7b4d8 100644
--- a/mftp/env.example.py
+++ b/mftp/env.example.py
@@ -22,7 +22,7 @@
HOSTER_EMAIL = ["hoster@kgpian.iitkgp.ac.in", "emergency.hoster@kgpian.iitkgp.ac.in"]
HOSTER_NAME = "Arpit Bhardwaj"
HOSTER_ROLL = ROLL_NUMBER
-HOSTER_INTERESTED_ROLLS = [HOSTER_ROLL, "XXYYXXXXX", "NNAANNNNN"]
+HOSTER_INTERESTED_ROLLS = ["XXYYXXXXX", "NNAANNNNN"]
# SHORTLIST CONFIG (MUST)
## Maps roll number to student names
diff --git a/mftp/mail.py b/mftp/mail.py
index d5f36ea..0905231 100644
--- a/mftp/mail.py
+++ b/mftp/mail.py
@@ -5,11 +5,144 @@
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
-from env import FROM_EMAIL, FROM_EMAIL_PASS, BCC_EMAIL_S, HOSTER_EMAIL
+from env import FROM_EMAIL, FROM_EMAIL_PASS, BCC_EMAIL_S, HOSTER_EMAIL, HOSTER_INTERESTED_ROLLS, ROLL_MAIL, ROLL_NAME
-def format_shortlist():
- pass
+def send_shortlists(mails, gmail_api, smtp):
+ print('[SENDING SHORTLIST UPDATES]', flush=True)
+
+ if gmail_api:
+ import base64
+
+ try:
+ service = generate_send_service()
+ except Exception as e:
+ logging.error(f" Failed to generate GMAIL API creds ~ {str(e)}")
+ return
+
+ for mail in mails:
+ try:
+ response = service.users().messages().send(
+ userId="me",
+ body={"raw": base64.urlsafe_b64encode(mail.as_bytes()).decode()}
+ ).execute()
+ except Exception as e:
+ logging.error(f" Failed to send request to GMAIL API : {mail['Subject']} -x-> ({mail['Bcc']}) ~ {str(e)}")
+ break
+
+ if 'id' in response:
+ logging.info(f" [MAIL SENT] ~ {mail['Subject']} -> ({mail['Bcc']})")
+ else:
+ logging.error(f" Failed to Send Mail : {mail['Subject']} -x-> ({mail['Bcc']}) ~ {response}")
+ break
+ elif smtp:
+ import ssl
+ import smtplib
+ context = ssl.create_default_context()
+
+ logging.info(" [Connecting to smtp.google.com] ...")
+ with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
+ logging.info(" [Connected!]")
+ try:
+ server.login(FROM_EMAIL, FROM_EMAIL_PASS)
+ logging.info(" [Logged In!]")
+ except Exception as e:
+ logging.error(f" Failed to log in ~ {str(e)}")
+ return
+
+ for mail in mails:
+ try:
+ server.sendmail(mail["From"], mail["Bcc"].split(', '), mail.as_string())
+ logging.info(f" [MAIL SENT] ~ {mail['Subject']} -> ({mail['Bcc']})")
+ except smtplib.SMTPException as e:
+ logging.error(f" Failed to Send Mail : {mail['Subject']} -x-> ({mail['Bcc']}) ~ {str(e)}")
+ break
+
+
+def format_shortlists(shortlists):
+ print('[FORMATTING SHORTLIST UPDATES]', flush=True)
+
+ table_body = """
+
+
+
+
+
+
+
+ {columns}
+
+
+
+ {rows}
+
+
+
+
+
+
+ """
+
+ host_interested_message = MIMEMultipart()
+ host_interested_message["Subject"] = "People you are interested in are shortlisted!"
+ host_interested_message["From"] = f'MFTP < {FROM_EMAIL} >'
+ host_interested_message["Bcc"] = ", ".join(HOSTER_EMAIL)
+
+ host_interested_cols = """
+ Name (count) |
+ Company (notice_id) |
+ """
+
+ def generate_row(company_shortlist):
+ return f"""
+
+ {company_shortlist['company']} (#{company_shortlist['id']}) |
+ {company_shortlist['count']} |
+
+ """
+
+ def generate_host_interested_row(name, company_shortlist):
+ return f"""
+
+ {name} ({company_shortlist['count']}) |
+ {company_shortlist['company']} (#{company_shortlist['id']}) |
+
+ """
+
+ host_interested_rows_list = []
+
+ mails = []
+ for roll, shortlist in shortlists.items():
+ if roll in HOSTER_INTERESTED_ROLLS:
+ name = ROLL_NAME.get(roll)
+ host_interested_rows_list += [generate_host_interested_row(name, company_shortlist) for company_shortlist in shortlist]
+
+ student_mails = ROLL_MAIL.get(roll)
+ if student_mails is None:
+ continue
+
+ message = MIMEMultipart()
+ message["Subject"] = "You have been shortlisted!"
+ message["From"] = f'MFTP < {FROM_EMAIL} >'
+ message["Bcc"] = ", ".join(student_mails)
+
+ rows = ''.join(generate_row(company_shortlist) for company_shortlist in shortlist)
+ columns = """
+ Company (notice_id) |
+ Count |
+ """
+
+ shortlist_table = table_body.format(columns=columns, rows=rows)
+ message.attach(MIMEText(shortlist_table, "html"))
+
+ mails.append(message)
+
+ host_interested_rows = ''.join(host_interested_rows_list)
+ host_interested_shortlist_table = table_body.format(columns=host_interested_cols, rows=host_interested_rows)
+ host_interested_message.attach(MIMEText(host_interested_shortlist_table, "html"))
+ mails.append(host_interested_message)
+
+ return mails
def send_companies(mail, gmail_api, smtp):
diff --git a/mftp/mftp.py b/mftp/mftp.py
index 479ff93..acbeb71 100644
--- a/mftp/mftp.py
+++ b/mftp/mftp.py
@@ -7,7 +7,6 @@
import company
import shortlist
-import logging
import requests
import argparse
from datetime import datetime
@@ -65,28 +64,10 @@
if args.gmail_api or args.smtp:
_, new, modified = company.fetch(session, headers, ssoToken)
- if new:
- print("[NEW COMPANIES]", flush=True)
- for com in new:
- logging.info(
- f" {com['Name']} | {com['Role']} | {com['CTC']} | {com['End_Date']} | {com['Interview_Date']}"
- )
- if modified:
- print("[MODIFIED COMPANIES]", flush=True)
- for com in modified:
- logging.info(
- f" {com['Name']} | {com['Role']} | {com['CTC']} | {com['End_Date']} | {com['Interview_Date']}"
- )
-
filtered = []
if new + modified:
filtered = company.filter(new + modified, "OPEN_N")
if filtered:
- for com in filtered:
- logging.info(
- f" {com['Name']} | {com['Role']} | {com['CTC']} | {com['End_Date']} | {com['Interview_Date']}"
- )
-
latest_ssoToken = session.cookies.get("ssoToken")
mail_subject = "APPLY NOW! New companies opened"
companies_mail = mail.format_companies(
@@ -111,7 +92,9 @@
else:
shortlists = shortlist.search(notices)
if shortlists:
- pass
+ shortlists_mails = mail.format_shortlists(shortlists)
+ if shortlists_mails:
+ mail.send_shortlists(shortlists_mails, args.gmail_api, args.ntfy)
mails = mail.format_notices(notices)
if mails:
mail.send_notices(mails, args.smtp, args.gmail_api, notice_db)
diff --git a/mftp/shortlist.py b/mftp/shortlist.py
index 21c29c0..f1c37db 100644
--- a/mftp/shortlist.py
+++ b/mftp/shortlist.py
@@ -2,35 +2,66 @@
import io
import PyPDF2
import logging
+from env import ROLL_NAME
from collections import defaultdict
-from env import HOSTER_INTERESTED_ROLLS, ROLL_MAIL, ROLL_NAME
def search(notices):
- print('[SEARCHING SHORTLISTS]', flush=True)
+ notice_wise_shortlists = search_notice_wise_shortlists(notices)
+ if notice_wise_shortlists:
+ student_wise_shortlists = calc_student_wise_shortlists(notice_wise_shortlists)
+ return student_wise_shortlists
+ else:
+ print("[NO NEW SHORTLISTS]", flush=True)
+ return defaultdict(list)
- shortlists = []
+
+def calc_student_wise_shortlists(notice_wise_shortlists):
+ print("[PARSING STUDENT WISE SHORTLISTS]", flush=True)
+
+ student_wise_shortlists = defaultdict(list)
+
+ for notice_shortlist in notice_wise_shortlists:
+ for roll, shortlists in notice_shortlist.items():
+ student = student_wise_shortlists[roll]
+ student.append(shortlists)
+
+ for roll, shortlists in student_wise_shortlists.items():
+ shortlists_str = " | ".join([
+ f"{shortlist['company']} (#{shortlist['id']}) [{shortlist['count']}]"
+ for shortlist in shortlists
+ ])
+ name = ROLL_NAME.get(roll)
+ logging.info(f" [{name} ({roll})]: {shortlists_str}")
+
+ return student_wise_shortlists
+
+
+def search_notice_wise_shortlists(notices):
+ print("[SEARCHING NOTICE WISE SHORTLISTS]", flush=True)
+
+ notice_wise_shortlists = []
for notice in notices:
# Handling Shortists in Body
try:
body_shortlists = search_body(notice)
if body_shortlists:
- shortlists.append(body_shortlists)
+ notice_wise_shortlists.append(body_shortlists)
except Exception as e:
logging.error(f" Failed to parse shortlists from notice body ~ {str(e)}")
continue
# Handling Shortlist in attachment
try:
- if 'Attachment' in notice:
+ if "Attachment" in notice:
attachment_shortlists = search_attachment(notice)
if attachment_shortlists:
- shortlists.append(attachment_shortlists)
+ notice_wise_shortlists.append(attachment_shortlists)
except Exception as e:
logging.error(f" Failed to parse shortlists from attachment ~ {str(e)}")
continue
- return shortlists
+ return notice_wise_shortlists
def search_body(notice):
@@ -38,23 +69,20 @@ def search_body(notice):
body_data = notice["BodyData"]
body = body_data.decode_contents(formatter="html")
- for roll in HOSTER_INTERESTED_ROLLS:
+ for roll in ROLL_NAME.keys():
count = body.count(roll)
if count > 0:
id_ = notice["UID"].split("_")[0]
company = notice["Company"]
name = ROLL_NAME.get(roll)
- mails = ROLL_MAIL.get(roll)
shortlists[roll] = {
"id": id_,
"company": company,
- "name": name,
"count": count,
- "mails": mails,
}
logging.info(
- f" [NOTICEBODY] {name} ({count}) -> {company} (#{id_})"
+ f" [NOTICEBODY] {name} ({roll}) [{count}] -> {company} (#{id_})"
)
return shortlists
@@ -64,23 +92,20 @@ def search_attachment(notice):
shortlists = defaultdict(dict)
attachment = notice["Attachment"]
- for roll in HOSTER_INTERESTED_ROLLS:
+ for roll in ROLL_NAME.keys():
count = parse_pdf_bytes(attachment, roll)
if count > 0:
id_ = notice["UID"].split("_")[0]
company = notice["Company"]
name = ROLL_NAME.get(roll)
- mails = ROLL_MAIL.get(roll)
shortlists[roll] = {
"id": id_,
"company": company,
- "name": name,
"count": count,
- "mails": mails,
}
logging.info(
- f" [ATTACHMENT] {name} ({count}) -> {company} (#{id_})"
+ f" [ATTACHMENT] {name} ({roll}) [{count}] -> {company} (#{id_})"
)
return shortlists