diff --git a/data/sqlite.db b/data/sqlite.db new file mode 100644 index 0000000..c90aa37 Binary files /dev/null and b/data/sqlite.db differ diff --git a/db/init.py b/db/init.py index e69de29..c228a84 100644 --- a/db/init.py +++ b/db/init.py @@ -0,0 +1,82 @@ +import sqlite3 +import uuid +import os + +os.makedirs("data", exist_ok=True) + +# Connect to SQLite database (creates file if not exists) +conn = sqlite3.connect("data/sqlite.db") +cursor = conn.cursor() + +# Enable foreign key support +cursor.execute("PRAGMA foreign_keys = ON;") + +# Create User table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS user ( + id TEXT PRIMARY KEY, + username TEXT UNIQUE NOT NULL +); +""") + +# Create Tokens table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS token ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE +); +""") + +# Create Calendar table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS calendar ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + name TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE +); +""") + +# Create Event table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS event ( + id TEXT PRIMARY KEY, + calendar_id TEXT NOT NULL, + title TEXT NOT NULL, + description TEXT, + start_time DATETIME NOT NULL, + end_time DATETIME NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY(calendar_id) REFERENCES calendar(id) ON DELETE CASCADE +); +""") + +conn.commit() + +print("Database and tables created successfully!") + +# Example: insert a user with a random UUID +user_id = str(uuid.uuid4()) +cursor.execute("INSERT INTO user (id, username) VALUES (?, ?)", (user_id, "alice")) + +# Example: insert a token for the user +token_id = str(uuid.uuid4()) +cursor.execute("INSERT INTO token (id, user_id) VALUES (?, ?)", (token_id, user_id)) + +# Example: insert a calendar for the user +calendar_id = str(uuid.uuid4()) +cursor.execute("INSERT INTO calendar (id, user_id, name) VALUES (?, ?, ?)", + (calendar_id, user_id, "Work Calendar")) + +# Example: insert an event for the calendar +event_id = str(uuid.uuid4()) +cursor.execute(""" +INSERT INTO event (id, calendar_id, title, description, start_time, end_time) +VALUES (?, ?, ?, ?, ?, ?) +""", (event_id, calendar_id, "Meeting", "Project sync-up", "2026-01-23 10:00", "2026-01-23 11:00")) + +conn.commit() +conn.close() \ No newline at end of file diff --git a/main.py b/main.py index 751092b..8fa8fb3 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,7 @@ from flask import Flask, request, send_file, render_template, Response import requests from requests_ntlm import HttpNtlmAuth import urllib +import html # ------------------------------------------------------------ # Config @@ -58,7 +59,7 @@ def get_events_data(page_data): for script in soup.head.find_all("script", {"type": "text/javascript"}): if not script.has_attr("src"): - source = script.text + source = html.unescape(script.text) break else: raise RuntimeError("Could not find inline timetable script") @@ -133,6 +134,19 @@ def build_calendar(page_data): now = ics_time(datetime.now(timezone.utc)) + # --- work out date range --- + if new_events: + start_dt = min(e["start"] for e in new_events) + end_dt = max(e["end"] for e in new_events) + + start_year = start_dt.year + start_month = start_dt.strftime("%b") + end_year = end_dt.year + end_month = end_dt.strftime("%b") + else: + # sensible fallback if no events + start_year = start_month = end_year = end_month = None + lines = [ "BEGIN:VCALENDAR", "VERSION:2.0", @@ -167,7 +181,9 @@ def build_calendar(page_data): lines.append("END:VCALENDAR") - return "\n".join(lines) + data = "\n".join(lines) + + return data, start_year, start_month, end_year, end_month # ------------------------------------------------------------ @@ -184,11 +200,11 @@ def login_and_download(): username = data["username"] password = data["password"] try: - data = build_calendar(fetch_timetable(f"COVENTRY\\{username}", password)) + data, start_year, start_month, end_year, end_month = build_calendar(fetch_timetable(f"COVENTRY\\{username}", password)) return Response( data, mimetype="text/calendar", - headers={"Content-Disposition": f'attachment; filename="{username}-timetable.ics"'}, + headers={"Content-Disposition": f'attachment; filename="{username}_timetable_{start_month}-{start_year}_to_{end_month}-{end_year}.ics"'}, ) except Exception as e: return render_template("login.jinja", error=str(e)), 401