change to use jinja2 and stop saving file and then reading the data
This commit is contained in:
92
main.py
92
main.py
@@ -3,22 +3,23 @@ from datetime import datetime, timezone
|
||||
import pytz
|
||||
import hashlib
|
||||
import os
|
||||
from flask import Flask, request, send_file, render_template
|
||||
from flask import Flask, request, send_file, render_template, Response
|
||||
import requests
|
||||
from requests_ntlm import HttpNtlmAuth
|
||||
import urllib
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Config
|
||||
# ------------------------------------------------------------
|
||||
|
||||
RESPONSE_FILE = "response.txt"
|
||||
OLD_CALENDAR = "old_calendar.ics"
|
||||
NEW_CALENDAR = "calendar.ics"
|
||||
LOCAL_TZ = pytz.timezone("Europe/London")
|
||||
URL = "https://webapp.coventry.ac.uk/Timetable-main/Timetable/Current"
|
||||
|
||||
print(URL.format(urllib.parse.quote_plus("hello/world")))
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
def parse_events(events_data):
|
||||
events_data = events_data.replace("new Date", "")
|
||||
cleaned_data = ""
|
||||
@@ -52,10 +53,7 @@ def parse_events(events_data):
|
||||
return parsed_data
|
||||
|
||||
|
||||
def get_events_data_from_file(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
page_data = f.read()
|
||||
|
||||
def get_events_data(page_data):
|
||||
soup = BeautifulSoup(page_data, features="html.parser")
|
||||
|
||||
for script in soup.head.find_all("script", {"type": "text/javascript"}):
|
||||
@@ -89,6 +87,7 @@ def create_ics_event(event):
|
||||
|
||||
def load_existing_uids(path):
|
||||
uids = set()
|
||||
return uids
|
||||
if not os.path.exists(path):
|
||||
return uids
|
||||
|
||||
@@ -111,6 +110,7 @@ def load_existing_uids(path):
|
||||
|
||||
return uids
|
||||
|
||||
|
||||
def fetch_timetable(username, password):
|
||||
session = requests.Session()
|
||||
session.auth = HttpNtlmAuth(username, password)
|
||||
@@ -118,16 +118,17 @@ def fetch_timetable(username, password):
|
||||
r = session.get(URL)
|
||||
r.raise_for_status()
|
||||
|
||||
with open("response.txt", "w", encoding="utf-8") as f:
|
||||
f.write(r.text)
|
||||
session.close()
|
||||
return r.text
|
||||
|
||||
def build_calendar():
|
||||
events_js = get_events_data_from_file(RESPONSE_FILE)
|
||||
|
||||
def build_calendar(page_data):
|
||||
events_js = get_events_data(page_data)
|
||||
parsed_events = parse_events(events_js)
|
||||
|
||||
new_events = [create_ics_event(e) for e in parsed_events if e]
|
||||
|
||||
old_uids = load_existing_uids(OLD_CALENDAR)
|
||||
old_uids = set()
|
||||
new_uids = {e["uid"] for e in new_events}
|
||||
|
||||
now = ics_time(datetime.now(timezone.utc))
|
||||
@@ -140,55 +141,58 @@ def build_calendar():
|
||||
]
|
||||
|
||||
for ev in new_events:
|
||||
lines.extend([
|
||||
"BEGIN:VEVENT",
|
||||
f"UID:{ev['uid']}",
|
||||
f"DTSTAMP:{now}",
|
||||
f"DTSTART:{ics_time(ev['start'])}",
|
||||
f"DTEND:{ics_time(ev['end'])}",
|
||||
f"SUMMARY:{ev['summary']}",
|
||||
f"DESCRIPTION:{ev['description']}",
|
||||
"END:VEVENT",
|
||||
])
|
||||
lines.extend(
|
||||
[
|
||||
"BEGIN:VEVENT",
|
||||
f"UID:{ev['uid']}",
|
||||
f"DTSTAMP:{now}",
|
||||
f"DTSTART:{ics_time(ev['start'])}",
|
||||
f"DTEND:{ics_time(ev['end'])}",
|
||||
f"SUMMARY:{ev['summary']}",
|
||||
f"DESCRIPTION:{ev['description']}",
|
||||
"END:VEVENT",
|
||||
]
|
||||
)
|
||||
|
||||
for uid in old_uids - new_uids:
|
||||
lines.extend([
|
||||
"BEGIN:VEVENT",
|
||||
f"UID:{uid}",
|
||||
f"DTSTAMP:{now}",
|
||||
"STATUS:CANCELLED",
|
||||
"END:VEVENT",
|
||||
])
|
||||
lines.extend(
|
||||
[
|
||||
"BEGIN:VEVENT",
|
||||
f"UID:{uid}",
|
||||
f"DTSTAMP:{now}",
|
||||
"STATUS:CANCELLED",
|
||||
"END:VEVENT",
|
||||
]
|
||||
)
|
||||
|
||||
lines.append("END:VCALENDAR")
|
||||
|
||||
with open(NEW_CALENDAR, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines))
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Flask
|
||||
# ------------------------------------------------------------
|
||||
@app.route("/")
|
||||
def index():
|
||||
return render_template("index.html")
|
||||
return render_template("login.jinja")
|
||||
|
||||
|
||||
@app.route("/login-and-download", methods=["POST"])
|
||||
def login_and_download():
|
||||
data = request.get_json()
|
||||
data = request.form
|
||||
username = data["username"]
|
||||
password = data["password"]
|
||||
username = f'COVENTRY\\{username}'
|
||||
try:
|
||||
fetch_timetable(username, password) #request
|
||||
build_calendar()
|
||||
return send_file(
|
||||
NEW_CALENDAR,
|
||||
as_attachment=True,
|
||||
download_name="timetable.ics",
|
||||
mimetype="text/calendar"
|
||||
data = build_calendar(fetch_timetable(f"COVENTRY\\{username}", password))
|
||||
return Response(
|
||||
data,
|
||||
mimetype="text/calendar",
|
||||
headers={"Content-Disposition": f'attachment; filename="{username}-timetable.ics"'},
|
||||
)
|
||||
except Exception as e:
|
||||
return str(e), 400
|
||||
return render_template("login.jinja", error=str(e)), 401
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
app.run(debug=True)
|
||||
|
||||
Reference in New Issue
Block a user