From f30df51649a511cc530ace9e4c7d07035226a7e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 22:54:03 +0000 Subject: [PATCH 01/10] Initial plan From cc8bcf51d83b199c6b151724d19d8ca8dd2c9556 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 22:58:30 +0000 Subject: [PATCH 02/10] Add time editing and manual entry features Co-authored-by: mschmid09 <88450858+mschmid09@users.noreply.github.com> --- app.py | 44 ++++++- core.py | 41 +++++++ templates/index.html | 15 +++ templates/manual_entry.html | 225 +++++++++++++++++++++++++++++++++++ templates/select_flight.html | 195 +++++++++++++++++++++++++++++- 5 files changed, 515 insertions(+), 5 deletions(-) create mode 100644 templates/manual_entry.html diff --git a/app.py b/app.py index f596584..b3645d4 100644 --- a/app.py +++ b/app.py @@ -4,7 +4,7 @@ import pandas as pd from flask import Flask, render_template, request, send_file, session -from core import get_flight, make_ics_from_selected_df_index +from core import get_flight, make_ics_from_selected_df_index, make_ics_from_manual_data app = Flask(__name__) @@ -42,11 +42,53 @@ def create_ical_from_selected(index): return "No flight data found", 400 df = pd.read_json(df_json, orient="split") + + # Check if custom times were provided + custom_departure = request.form.get("custom_departure") + custom_arrival = request.form.get("custom_arrival") + + if custom_departure and custom_arrival: + # Update the DataFrame with custom times + df.at[index, "scheduled_departure"] = custom_departure + df.at[index, "scheduled_arrival"] = custom_arrival + ics_data = make_ics_from_selected_df_index(df, index) flight = df.iloc[index]["flight_number"] return send_file(ics_data, as_attachment=True, download_name=f"{flight}.ics") +@app.route("/manual_entry") +def manual_entry(): + return render_template("manual_entry.html") + + +@app.route("/create_manual_event", methods=["POST"]) +def create_manual_event(): + try: + # Get all form data + flight_data = { + "flight_number": request.form.get("flight_number"), + "airline_name": request.form.get("airline_name"), + "origin_airport": request.form.get("origin_airport"), + "origin_airport_code": request.form.get("origin_airport_code"), + "destination_airport": request.form.get("destination_airport"), + "destination_airport_code": request.form.get("destination_airport_code"), + "scheduled_departure": request.form.get("scheduled_departure"), + "scheduled_arrival": request.form.get("scheduled_arrival"), + "origin_timezone": request.form.get("origin_timezone"), + "destination_timezone": request.form.get("destination_timezone"), + } + + # Create iCal file from manual data + ics_data = make_ics_from_manual_data(flight_data) + flight = flight_data["flight_number"] + + return send_file(ics_data, as_attachment=True, download_name=f"{flight}.ics") + except Exception as e: + error_message = str(e) + return render_template("manual_entry.html", error=error_message) + + if __name__ == "__main__": app.run() diff --git a/core.py b/core.py index cf9f7b0..0105812 100644 --- a/core.py +++ b/core.py @@ -238,3 +238,44 @@ def make_ical_event(data: dict): def save_ical_event(ical_event: bytes): ical_bytes = io.BytesIO(ical_event) return ical_bytes + + +def make_ics_from_manual_data(data: dict): + """Create iCal event from manually entered data.""" + cal = icalendar.Calendar() + cal.add("prodid", "-//eluceo/ical//2.0/EN") + cal.add("version", "2.0") + cal.add("calscale", "GREGORIAN") + cal.add("method", "REQUEST") + + event = icalendar.Event() + event.add( + "summary", + f'🛫 {data["airline_name"]} {data["origin_airport_code"]} ➡️ ' + f'{data["destination_airport_code"]} {data["flight_number"]}', + ) + + origin_tz = timezone(data["origin_timezone"]) + destination_tz = timezone(data["destination_timezone"]) + + # Parse datetime-local format "YYYY-MM-DDTHH:MM" to datetime + dtstart = origin_tz.localize( + datetime.strptime(data["scheduled_departure"], "%Y-%m-%dT%H:%M") + ) + dtend = destination_tz.localize( + datetime.strptime(data["scheduled_arrival"], "%Y-%m-%dT%H:%M") + ) + + event.add("dtstart", dtstart) + event.add("dtend", dtend) + event.add("location", f'{data["origin_airport"]}') + event.add( + "description", + f'{data["airline_name"]} flight {data["flight_number"]} / Departs {data["origin_airport"]}, {data["origin_airport_code"]}', + ) + event.add("dtstamp", datetime.now()) + event.add("status", "CONFIRMED") + + cal.add_component(event) + ical_event = cal.to_ical() + return save_ical_event(ical_event) diff --git a/templates/index.html b/templates/index.html index 49fe5e4..729a357 100644 --- a/templates/index.html +++ b/templates/index.html @@ -64,6 +64,20 @@ input[type="submit"]:hover { background-color: #0056b3; } + .manual-entry-button { + margin-top: 15px; + padding: 10px 20px; + border: none; + border-radius: 5px; + background-color: #28a745; + color: white; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; + } + .manual-entry-button:hover { + background-color: #218838; + } .emoji { font-size: 5rem; cursor: pointer; @@ -95,6 +109,7 @@
Enter your flight number and date to create an iCal event.
diff --git a/templates/manual_entry.html b/templates/manual_entry.html new file mode 100644 index 0000000..4d76121 --- /dev/null +++ b/templates/manual_entry.html @@ -0,0 +1,225 @@ + + + +Enter your flight details manually
+ +