Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added flask app #132

Merged
merged 13 commits into from
Jul 23, 2024
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ beautifulsoup4==4.12.2
google_api_python_client==2.90.0
httplib2==0.22.0
icalendar==5.0.7
iitkgp_erp_login
iitkgp_erp_login==2.3.7
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved
oauth2client==4.1.3
pytz==2023.3
Requests==2.31.0
65 changes: 65 additions & 0 deletions server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import requests
# from flask import Flask
from flask import Flask, request,send_file
from timetable import build_courses, generate_ics
import io

from flask_cors import CORS
from session_manager import SessionManager

app = Flask(__name__)
CORS(app, support_credentials=True)



@app.route("/secret-question", methods=["POST"])
def get_secret_question():
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved
data = request.form
roll = data.get("roll")
secret_question = SessionManager.get_secret_question(roll)
return secret_question
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved


@app.route("/send-otp", methods=["POST"])
def sendOTP():
data = request.form
roll = data.get("roll")
passw = data.get("pass")
secret_answer = data.get("secret_answer")

SessionManager.send_otp(roll, passw, secret_answer)

return "OTP sent"
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved


@app.route("/verify-otp-and-download", methods=["POST"])
def verifyOTPAndDownloadICS():
data = request.form
roll = data.get("roll")
email_otp = data.get("email_otp")

erp_session = SessionManager.create_erp_session(roll, email_otp)

timetable_page = erp_session.post(erp_session.ERP_TIMETABLE_URL, cookies=True,
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved
data=erp_session.get_timetable_details())
course_names = erp_session.get_course_names()
courses = build_courses(timetable_page.text, course_names)

print(f"Timetable fetched.\n")
ics_content = generate_ics(courses, "")

# Create an in-memory file-like object for the ics content
ics_file = io.BytesIO()
ics_file.write(ics_content.encode('utf-8'))
ics_file.seek(0) # Reset file pointer to the beginning

SessionManager.end_session(roll)
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved

# Return the ics file
return send_file(ics_file, mimetype='text/calendar', as_attachment=True, download_name='timetable.ics')


if __name__ == '__main__':
# Run the application on the local development server
app.run()

44 changes: 44 additions & 0 deletions session_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import iitkgp_erp_login.erp as erp
import requests
from utils import ERPSession

headers = {
'timeout': '20',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',
}
session = requests.Session()


class SessionManager:
rollTologinDetailsMap = {}
rollToSessionTokenMap = {}
tanush-128 marked this conversation as resolved.
Show resolved Hide resolved

@staticmethod
def get_secret_question(roll):
sessionToken = erp.get_sessiontoken(session)
SessionManager.rollToSessionTokenMap[roll] = sessionToken
secret_question = erp.get_secret_question(headers, session, roll)
return secret_question

@staticmethod
def send_otp(roll, passw, secret_answer):
sessionToken = SessionManager.rollToSessionTokenMap[roll]
loginDetails = erp.get_login_details(roll, passw, secret_answer, sessionToken)
SessionManager.rollTologinDetailsMap[roll] = loginDetails
erp.request_otp(headers, session, loginDetails)


@staticmethod
def create_erp_session(roll, email_otp):
loginDetails = SessionManager.rollTologinDetailsMap[roll]
loginDetails["email_otp"] = email_otp
ssoToken = erp.signin(headers, session, loginDetails)
erp_session = ERPSession.create_erp_session(session, ssoToken, roll)
return erp_session

@staticmethod
def end_session(roll):
SessionManager.rollTologinDetailsMap.pop(roll)
SessionManager.rollToSessionTokenMap.pop(roll)
return "Session ended"

12 changes: 8 additions & 4 deletions timetable/generate_ics.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ def generate_ics(courses: list[Course], output_filename):
event.add("dtstart", holiday[1])
event.add("dtend", holiday[1] + timedelta(days=1))
cal.add_component(event)

with open(output_filename, "wb") as f:
f.write(cal.to_ical())
print("\nYour timetable has been written to %s" % output_filename)


if output_filename != "":
with open(output_filename, "wb") as f:
f.write(cal.to_ical())
print("\nYour timetable has been written to %s" % output_filename)

return cal.to_ical().decode('utf-8')
6 changes: 6 additions & 0 deletions utils/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ class ERPSession:
ERP_TIMETABLE_URL: str = "https://erp.iitkgp.ac.in/Acad/student/view_stud_time_table.jsp"
COURSES_URL: str = "https://erp.iitkgp.ac.in/Academic/student_performance_details_ug.htm?semno={}&rollno={}"

#method to create erp session from login details, session and and ssotoken

@classmethod
def create_erp_session(cls, session: Session, sso_token: str, roll_number: str) -> 'ERPSession':
return cls(session=session, sso_token=sso_token, roll_number=roll_number)

tanush-128 marked this conversation as resolved.
Show resolved Hide resolved
@classmethod
def login(cls):
r"""
Expand Down